Hold submit until embedded work drains
x-lt-submit-guardx-lt-widget: escalation-listx-lt-actionsautoResolveWhenEmptyA parent form's submit stays disabled while its child rows are open, and can close itself the moment the last one resolves.
The situation
A picker closes out an order after picking each of its items. Each item is its own row, claimed to the picker. The order should not close while any item is still open, and the picker should not have to leave the page to finish them.
The recipe
Declare the child query once and use it for the list, its inline actions, and the guard:
{ "x-lt-submit-guard": { "query": { "role": "order-items", "facets": { "orderId": "{{metadata.orderId}}" }, "assigned": "me" }, "message": "{{count}} item(s) still pending. Pick them before closing the order.", "autoResolveWhenEmpty": true }, "type": "object", "properties": { "items": { "type": "string", "readOnly": true, "x-lt-widget": "escalation-list", "x-lt-query": { "role": "order-items", "facets": { "orderId": "{{metadata.orderId}}" }, "assigned": "me" }, "x-lt-actions": [ { "label": "Picked", "resolverPayload": { "picked": true, "orderId": "{{metadata.orderId}}" } } ] } }}The picker clicks Picked on each row. The count beside the locked submit falls with each click, and with autoResolveWhenEmpty the order submits itself once the query is confirmed empty.
The guarantee
Only a confirmed empty read clears the gate: while loading, on an error or on a 403, the submit stays disabled. For enforce_schema roles the server runs the same query at resolve and rejects with a canonical 422 while it returns rows, counting the true children regardless of the resolver’s read scope. The guard and the embedded list resolve through one shared mapping, so the count and the visible rows always agree. See Forms.
Related patterns
Forms and configuration
Roster: check off who arrived
A roster lists every member a container expects, marks each waiting, in or flagged, and holds the rest of the form until all are accounted for.
The queue as a market
Claim complete groups
A consumer claims whole orders, every unit at once, and only orders whose units have all arrived. No order is ever split across consumers.
Forms and configuration
Conditional fields
A field appears only when a condition holds, live as the person types, and a hidden required field is skipped by validation on both sides.
