What happens now
When an interface reference (<expr> INTERFACE Foo) targets a TRANSACTIONAL interface Foo, the referenced subinterface renders without its transaction bar (SAVE/CANCEL) and without buffering — its fields render inline and autosave, as if the interface were not transactional.
Empirically (v2.4.6 / Ampersand v5.9.2):
Foo rendered as |
own <app-foo> component |
transaction bar |
| top-level (route / embed) |
yes |
yes |
<expr> INTERFACE Foo (subinterface reference) |
no |
no |
Cause
A reference is compiled by inlining the referenced interface's box into the parent component's template (<app-box-form propertyName="foo" [data]="[resource.foo]">) instead of instantiating Foo's own component. The transaction bar is mounted in ampersand-interface.class.ts → setResource() → mountTransactionBar() when resolveMode()==='Transactional', and that only runs inside an instantiated interface component. An inlined referenced box never reaches it.
Note: @HostBinding('class.ampersand-transactional-interface') already carries the comment "required by the TRANSACTIONAL feature (also for subinterfaces)" — the intent for transactional subinterfaces exists; the mount path just isn't reached for references.
Desired
A referenced TRANSACTIONAL subinterface gets its transaction bar (its own buffer + SAVE), just like when rendered top-level.
Minimal repro
A non-transactional wrapper that references a TRANSACTIONAL interface as a subinterface:
INTERFACE Wrapper : I[SESSION] cRud BOX<FORM>
[ "x" : <expr> INTERFACE Login ] -- Login is a TRANSACTIONAL INTERFACE
Done when the login commits via a transaction bar rendered at the subinterface.
What happens now
When an interface reference (
<expr> INTERFACE Foo) targets aTRANSACTIONALinterfaceFoo, the referenced subinterface renders without its transaction bar (SAVE/CANCEL) and without buffering — its fields render inline and autosave, as if the interface were not transactional.Empirically (v2.4.6 / Ampersand v5.9.2):
Foorendered as<app-foo>component<expr> INTERFACE Foo(subinterface reference)Cause
A reference is compiled by inlining the referenced interface's box into the parent component's template (
<app-box-form propertyName="foo" [data]="[resource.foo]">) instead of instantiatingFoo's own component. The transaction bar is mounted inampersand-interface.class.ts→setResource()→mountTransactionBar()whenresolveMode()==='Transactional', and that only runs inside an instantiated interface component. An inlined referenced box never reaches it.Note:
@HostBinding('class.ampersand-transactional-interface')already carries the comment "required by the TRANSACTIONAL feature (also for subinterfaces)" — the intent for transactional subinterfaces exists; the mount path just isn't reached for references.Desired
A referenced
TRANSACTIONALsubinterface gets its transaction bar (its own buffer + SAVE), just like when rendered top-level.Minimal repro
A non-transactional wrapper that references a
TRANSACTIONALinterface as a subinterface:Done when the login commits via a transaction bar rendered at the subinterface.