Beginner question on using cells for a rich UI

More basic questions from me, sorry if this is all beginner stuff. (As I mentioned in other questions, I’m coming from more of a backend/ML background and the only frontend stuff I know was basically HTML 1.0 back in the 90s, and now I’ve jumped directly to Redwood/React/JS after managing to mostly ignore frontend for decades, aside from a tiny bit of ObjectiveC and Java work on mobile).

So I’m building a web app with an annoyingly large user interface – dashboards, lots of data entry elements, etc. (not that it matters much, but I’m starting with Mantine instead of e.g. TailwindCSS to try to leverage a little pre-built UI). Several questions here, as the amount of code to write feels a little overwhelming. Trying to get started ensuring I have a the right process and architecture.

  1. I think I can compose a dashboard out of a bunch of smaller components I write that can be reused. E.g. say I have a list of Items in an Inventory, maybe I want a panel that shows a table of Items. I think then I can make an Items cell that handles the fetching and display of the table of items. So far so good, this is just like in the auto-generated scaffolds.

Now, what if I want each item in the table to be editable inline (as opposed to on a separate “edit” page?) For example, if the item has a “quantity” field I’d like to be able to click that and edit the quantity, and save the result to the DB immediately. Several subquestions here:

  1. Is the best approach a monolithic “Items” component that detects which cell is being edited and then makes the appropriate mutation? Or is it better to model this as a display component that generates a whole list of individual Row components, and each of those is responsible for its own mutations? Essentially, when I want most items in my UI to be editable, and I want to maximize code reuse, can I be pushing the view/mutate logic down to the individual rows (or items within a row), or should it stay in a higher-level component? Note that I might want custom edit logic for each column; some will be text boxes, some dropdowns, etc. So my first instinct is that every little piece of editable data in the UI should manage its own DB relationships. (say, I pick an item from a dropdown, and that single row/column item will have its own Redwood “Cell”… but then again this sounds like it might lead to way to much network traffic). If I try to do everything in a higher-order component, though, it feels like a ton of bespoke logic that I’ll have to rewrite for each different view of the data.

  2. If I click on an item in a table, I might open up a separate “detail view” panel in the dashboard. If so, again how do I reuse the logic for displaying/editing that I had in the table view? Will there be a separate Redwood “Cell” for an “Item Detail View” and a totally different Cell for “Items list”? Can there be any code reuse between the two?

Overall I’m going to have a lot of tables and a lot of detail views for various lists of various types of objects, each with their own model classes. I want to be able to build a slick interface to view/edit/add/delete, minimizing code duplication, and avoiding separate “edit/save” views.

  1. I want to auto-update the DB on every edit, but I also want to be doing an optimistic update of the local UI. Do I get this “for free” with the built-in Apollo client magic, or do I need to config or write code explicitly to enable this behavior?

  2. Can I make my app work in a “localStorage” mode, so that as a user interacts with the rich UI, and their updates are added to the DB, it’s all happening locally if the network is down? And then would there be a way to push all local states up to the DB in bulk once the network is restored? I feel like this is the kind of thing Apollo might do with little effort, but maybe I’m hoping for too much. If I always work in the context of Redwood Cells for data mutations, will it be making use of local storage/local cache somehow? A pure local-mode app isn’t a requirement for my project, but I’m trying to better understand what Apollo can do automatically. Overall, I’m trying to avoid having UI elements like “Save Data” buttons – I want edits to get pushed to the DB in a way that doesn’t require extra user effort.

Sorry those questions were a little redundant, but I hope they give an idea of what I’m going for. I really like the Redwood Cell support for loading/empty/error/results, but I want to make sure I’m using them correctly when building a rich hierarchical interface. Thanks for any advice!

Those are all great questions @eraoul! But this is not an easy topic. Designing this in a good way is something you’d normally discuss with a tech lead on your team or your CTO depending on how big of a company you work for. For a side-project you’re going to have to take all that on yourself :sweat_smile:

I’d suggest just getting something working first, and then rewrite and optimize as needed. Starting with just rendering form components in your list view, and passing in the value and an onChange callback that calls your mutate function is probably a good start.

When you get that working you can look at these Apollo Client docs Optimistic mutation results - Apollo GraphQL Docs

And when that is also working, you can see about persisting the cache in localStorage with something like GitHub - apollographql/apollo-cache-persist: 🎏 Simple persistence for all Apollo Cache implementations

Thank you! OK sounds like at least I’m not totally on the wrong track then. Appreciate it!