I am trying to play with LiveBook as a research playground to analyze data and create first ugly prototypes of the internal or not so internal tool (isn’t it what such notebooks are good for?).
Concept
We are operating in the hiring space and idea is pretty much like:
Select a job ad from currently open ones (or based on some other criteria)
Select some applicant
Fetch extra information that we happen to know about the applicant (e.g. history from the past jobs)
Ask AI to analyze the results and provide automated opinion on this or that characteristic
Selecting in DataTable - how to do it
So as you see there are a couple of steps which are about presenting long list of records (with some details) and choosing something there. Number of records is like dozens to thousands so for a research prototype I don’t really care about any kind of caching.
I though that Kino.DataTable should be a good choice for it as it has built-in pagination and search (though search just highlights items instead of filtering or I don’t know how to hide unmatching stuff easily).
But… I failed to figure how to register any sort of “clicked” or “selected” events in datatable. There seem to be ways to do it for a Button, so I thought i could use datatable’s formatter to inject button somewhere, but it also seems not possible.
How to select from a long list of records in LiveBook [easily]?
What would you in such a case? Or what do you use already?
I figured a way to use select control, but it really is not made for looking at many record details and looks wrong when you want to make a conscious choice of many records.
Is my only option to create a clone of DataTable or is there a known hack or a different control to make a choice between many elements easy?
There is currently no API do to that with data table. In general, you could implement a custom table output and have an Elixir API to get the currently selected row, but the thing is that the changes won’t be tracked. If the user selects a different row, the cell that read the current value won’t be marked as stale (as is the case for Kino.Input.read/1). The change tracking only works with built-in inputs. This wouldn’t be a problem if, instead of reading the current value, the API was to receive an update (like Kino.Control components), but this would imply the “reactive app” style, where you kinda need to write everything in a single cell to handle events and update frames. Perhaps in the future we could add an abstraction for creating custom inputs with proper change tracking, but that’s not one the roadmap currently.
So if you want to rely on input reading, you need to either use a select, or perhaps render the table with ids, and have a text field below where the user enters the id(s) (definitely not the best UX, but allows you to use the table).
Thanks, @jonatanklosko I remade my R&D livebooks to mostly go via Kino.Input.Read and builtin controls and it works well even if not exactly per the imagined UI.
May I ask what is the Kino controls customizability development direction (if such a thing exists at all)?
Because of the current topic, I browsed quite a lot of Kino code (well, a lot to my not so high elixir skills) and it didn’t look like there are any natural extension points pretty much anywhere. Like no way to plug in own rich renders for table cells, no way to add own events and so forth?
Are these extension points not done on purpose (like “livebook should not really be used for intercell apps, go do own controls and event publish-subscribe if you need it”)?
Or is it planned for some future time?
Or is it just out of the current focus and not given a big thought?
@artem the extension-points that kino providers are higher level, mainly:
customize how certain data structures are visualized via the Kino.Render protocol
implement custom widgets to arbitrarily visualize outputs via Kino.JS/Kino.JS.Live
create custom Smart cells to generate code from UI (such as Chart cell for generating charts)
Specific components can be extended via options where appropriate. For example Kino.DataTable accepts :formatter option to customize how certain columns are formatted, though it only allows returning a string. If by rich render you mean a formatter that returns another Kino, then yeah, it doesn’t compose on that level in this case. The table specifically is implemented in JS on top of Glide Data Grid, which uses canvas, so there’s likely no way for us to have straightforward API allowing the user to arbitrarily customize how a cell is rendered from Elixir.