Master-detail (Process + Steps)
A master-detail UI in Mateu is built by embedding a child CRUD orchestrator inside a parent screen, not by using List<Entity>.
The pattern applies to any parent-child relationship: Order + OrderLines, Customer + Contacts, Project + Tasks. This page uses a Process + Steps example to show the mechanics clearly. The golden example applies the same pattern to Orders and OrderLines with a full backend stack.
We want:
- a Process (parent)
- a list of Steps (children)
- full CRUD on Steps inside the Process screen
Process (parent)
Section titled “Process (parent)”@Route("/processes/:id")@Style(StyleConstants.CONTAINER)public class ProcessPage {
String id;
String name;
Callable<?> steps = () -> MateuBeanProvider .getBean(Steps.class) .withProcessId(id);
}Key idea
Section titled “Key idea”stepsis NOTList<Step>- it is a dynamic UI block
- resolved after the viewmodel is hydrated
Steps (child CRUD)
Section titled “Steps (child CRUD)”public class Steps extends AutoListOrchestrator<Step> {
String processId;
public Steps withProcessId(String processId) { this.processId = processId; return this; }
}Step model
Section titled “Step model”record Step( String id, String processId, String name) {}What Mateu generates
Section titled “What Mateu generates”Inside the Process screen:
- list of steps
- create step
- edit step
- delete step
All scoped by processId
Why this approach
Section titled “Why this approach”This is preferred over:
List<Step> steps;Because:
List<Step>becomes a simple editable structure- it does NOT provide full CRUD behavior
- it couples UI to domain structure
Mental model
Section titled “Mental model”flowchart TD P["ProcessPage\nid · name · Callable<?> steps"] P -->|resolves after hydration| S["Steps\nextends AutoListOrchestrator<Step>\nscoped by processId"] S --> CR["Full CRUD on Step\nlist · create · edit · delete"]- parent → state + composition
- child → independent CRUD
- composition →
Callable<?>
When to use
Section titled “When to use”Use this pattern when:
- child entities have their own lifecycle
- you need CRUD inside another screen
- you want explicit control over data boundaries
Summary
Section titled “Summary”- do NOT model child collections as
List<Entity> - use embedded orchestrators instead
- compose using
Callable<?>
This is the Mateu way to build master-detail UIs.
- Relationships vs embedded CRUDs — when to use
@Lookup,List<Entity>, or an embedded orchestrator - Golden example: Orders, Customers and Order lines — the same pattern applied with a full adapter and repository stack