Fork me on GitHub

@tony.kay - what are your thoughts on rad-report generating columns with eql joins? Obviously, the item :query can be modified to do a join, but do you think the ::report/columns syntax will support this idea? Or do you expect that this would be accomplished via a custom pathom resolver (i.e. to "flatten" a nested value into the primary entity)? Or is this currently out of scope and would require dropping down to a custom render body?


Possibly related: I think it would be a beneficial escape hatch, if we could pass in a column-name->custom-render-fn to defsc-report, such that we could pass in a custom render function (that includes in the arguments the existing props; but dispatches on column-name and not attribute kind). Then you can always define "computed custom columns" for rendering purposes, that don't necessarily map to actual attributes.


@pithyless rad forms has yet to be formally designed. The nested stuff is completely unstable and will change on report.


At present, when I use reports I do not use anything but a plain defsc with a body for the rows. Autogeneration of rows will likely require you write a component and then call perhaps a function from the control map that you install…I’m open to ideas, but it needs to support recursion for sure


you don’t want that customization on the component options (except as a keyword perhaps), since you don’t want platform dependent rendering in the rendering code path


I updated the book with some comments on this last night:


forms is still my central task until I get them working well in our production app…I’m close 🙂


I just needed enough of reports (so far) to get a master-detail CRUD system going.


My goal is to have forms running in our production app by Wednesday, at which point the documented features of forms will be relatively stable (still alpha and subject to change based on experience)…at which point I can turn to reports.


The main likely API change on all of this is that many of the keys will start to allow functions as well as scalars so you can dynamically change your mind at runtime.


I’ve started adding support for that, but it isn’t everywhere yet, and I’m not sure what will be passed as args


Yeah, I noticed the ?! convention :]


sbject to rename, but seemed like a decent “optionally run” notation


Fair enough, no need to apply the alpha* clause to every statement you make about rad, I'm aware this is alpha-api territory. 🙂 I'm just chugging along quietly with my own CRUD experiments, but I've dropped a lot of my original UI rendering stuff and have steadily moved to just tracking and adopting the approach from the fulcro-rad repo. Looking forward to the form/report updates as your ideas stabilize.


yeah, I suspect you know…just want anyone reading along reminded 🙂


If you’re interested in collaborating, I’d love the help.


> you don’t want that customization on the component options (except as a keyword perhaps), since you don’t want platform dependent rendering in the rendering code path This is an interesting point; wonder what kind of balance you can reach on the spectrum: ["re-implement everything you want custom" ... "your dispatch is customized only on attr/type" ... "by default you only get pr-str"]. Maybe a keyword-based dispatch would be good enough.


well, the current installation of controls is what I mean. Anything that is platform-dependent should be installed there at startup so only your entry point is dependent on the UI platform.


as an old UNIX hack, I think it’d be fun to make a UNIX Curses JVM lib so we could render RAD to text terminals 😜

😂 12

then it would just run in CLJ, not even cljs…silly, but fun


yeah, that's cool; but currently the controls are dispatched only on attr/type. Since EQL is promoting maximal graphs, maybe it wouldn't be that crazy if the controls had a global dispatch mechanism based on the attr/qualified-key (optional)


not sure I understand that stmt…dispatch for what?


you can put a field style on the attribute, or at the form…but that’s what picks the rendering


the former is exactly that, but not so open to explosion of dispatch


ah! I forgot about ::form/field-styles


I have 1000 attrs, I don’t want 1000 entries in render dispatch…I prob only have about 20 real control renderings


right, singular on attribute


plural on the form


So yeah, to sum up my original question; I guess it was about a future ::report/field-styles


diff attr for diff type of thing


of course, I expect report to (somewhat) mirror forms.


Sorry for the rambling; I'll let you get back to it. :]


prob a macro or function to make the row ui shorter to write is fine. For now, something like this is what a macro would generate:

(defsc Row [this props]
  {:query [:props]
   :ident :row/id}
  (report/render-row this props))
where anything you drop in the component options would be available to the row rendering code.


that’s all defsc-report and defsc-form really do, other than some error checking and autogen of query/ident/routing stuff.


then render-row would just look up the custom row layout, etc.


and yes, a ::report/column-styles map is certainly in the mix


as is a ::report/row-actions


want to at least support redirecting to a form for editing, or triggering an entity delete through form/delete!, but general function support would be fine there.


Mainly the trick is minimizing the input the user has to give down to the minimal novelty 🙂


Yeah, so my original poorly phrased question about column-name->custom-render-fn is essentially ::report/column-styles ; And the other question was whether column values can be generated dynamically (and not backed by an actual defattr).


I'm having trouble with upload-files mutation, the middlewares are placed, it ran before but now the TX gets stuck under pending state


@pithyless “generated dynamically”…yes, but declared with defattr still…they just won’t be reified into a storage schema. See


last part of that section


Also, I expect to integrate client-side processing as well. For forms that would be some kind of middleware that would be called as the form changes.


for reports I’d expect that there would be something like a generated column thing…not sure how that would plug in just yet. ::report/generated-columns , but could pretty easily justify still using defattr for that, and add a ::report/value-generator that receives the whole report and the current row as (fn [report row] value)


but you still want the defattr to declare things like type, style, etc.


at that point report could probably just detect what is a client-generated attribute, and you’d just include it in the list of things you want on a row


Ultimately I see at least 3 layers: 1. The portion of the report/form query that goes to a server. This might need to be split across multiple servers, but is directed to remotes based on a bit more config that I have not invented yet. The servers can generate derived values if that makes sense. The Pathom parser lives on the server. 2. Parts of the query that are handled by a client-side pathom (i.e. to talk to REST, GraphQL, etc. directly). This pathom parser lives on the client. 3. A computation layer at the client where you could plug in any kind of computation.


I have an component data structure where a Rule contains one RulCond (just its name!). There are two types of RulCond, container and leaf. Container's have children. So arbitrary recursion. I'm trying to add forms to this, but having some trouble. Wondering whether having {:rulcond/children '...} in :query of RulCond is not supported?



{:rulcond/children '...}
{:rulcond/children (comp/get-query RulCond2)}
, where RulCond2 is just a copy of RulCond fixes all these forms issues (it was more than just about form config not being put into the app state entity/row).


Forms and don’t get along


So I got rid of ... in the real app and replaced with RulCond/RulCond1/RulCond2/RulCond3/RulCond4 . An interesting consequence of this is that queries going to the server always go the full distance.


I had the code for dirty-fields sitting there ready to attempt a fix. But I take it that would have been a frustrating and futile experience. @tony.kay


well, not futile, but possibly frustrating 😜


It has been a very long time since I looked at that code, but it is probably tractable to fix