fix: deliver stepper onEnter after the activating render - #5604
Merged
norman-abramovitz merged 5 commits intoJul 8, 2026
Merged
Conversation
SteppersComponent.setActive called pOnEnter synchronously after switching currentIndex, but step content instantiates lazily on the NEXT render (ngTemplateOutlet on currentIndex). Signal-handle onEnter bodies that dereference a @ViewChild therefore ran against undefined and the enter callback was silently dropped for every step after the first. Delivery is now deferred via afterNextRender (active-step guarded), on both the main path and the first-step blocked-wait path. In the bind-service wizard this dropped onEnter meant formMode was never set and the Service Instance step rendered completely empty. Delivery alone is not enough under zoneless+OnPush: onEnter now runs outside change detection, and the step's first render happened with every @if false, so template-bound fields written in onEnter must be signals. Converted specify-details' formMode and bind-apps' schemaFormConfig; the bind-apps hand-off also restores the plan schema driving the Binding Parameters editor. Live-verified: app -> Bind Service -> Marketplace -> postgresql -> cluster -> Binding Params -> Service Instance renders the create form. Closes cloudfoundry#5600
create-endpoint and git-registration handed the registration result to the connect child inside step 1's submit — but the connect child does not exist at submit time (step content instantiates on activation), so the guarded this.connect.onEnter(...) silently no-oped and the connect step never received the endpoint it should connect. The result now returns through submit's data channel and the stepper delivers it to the connect handle's onEnter after the activating render. Both wizards' valid/finishButtonText computeds also dereferenced a plain @ViewChild field: a computed whose first evaluation sees an undefined child captures zero signal dependencies and never re-evaluates. The connect ViewChild is now signal-backed.
The kube-config registration wizard assumed both step children exist for the wizard's lifetime, but the stepper instantiates step content lazily on activation: - ngAfterViewInit bridged importer.busy$ when the importer did not exist yet; bridges now live in ViewChild setters. - The review step's onEnter pulled clusters from the selection step's helper after that child (and its component-scoped provider) was destroyed. KubeConfigHelper is now provided by the wizard so the parsed clusters survive step transitions. - Step 1's [applyStarted] bound across steps into the never-alive importer; canClose/destructiveStep/finishButtonText computeds froze against the same undefined ViewChild. applyStarted is now a parent-owned signal mirroring the importer's lifecycle (reset on review entry, set on first Import click).
make test frontend PROJECT=<vitest project(s)> SCOPE=<path filter> runs a subset for the edit-test loop; the npm test script hard-codes every --project so narrowed runs invoke vitest directly with the same unhandled-errors flag. Bare 'make test frontend' is unchanged.
norman-abramovitz
marked this pull request as ready for review
July 8, 2026 17:38
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #5600
Problem
SteppersComponent.setActivecalledpOnEntersynchronously after switchingcurrentIndex, but step content is instantiated lazily by thengTemplateOutleton the next render. Every signal-handleonEnterthat dereferences a@ViewChildof the entering step ran againstundefinedand was silently dropped.In the bind-service wizard that meant
formModewas never set, so the Service Instance step rendered empty (#5600). The same drop affected the deploy-application hand-offs (FileScannerInfo, deployer), the register-to-connect hand-off in create-endpoint / git-registration, and most of the kube-config registration wizard.Fix
pOnEnterdelivery is deferred viaafterNextRender(active-step guarded) on both the main path and the first-step blocked-wait path, so ViewChilds exist when handle bodies run. Regression spec added.onEnternow runs outside change detection, and the step's first render has every@iffalse — template-bound fields written inonEnterare now signals (formMode,schemaFormConfig). The bind-apps hand-off also restores the plan schema driving the Binding Parameters editor.datachannel to the connect handle'sonEnter(the direct call at submit time ran before the connect child existed); connect ViewChild is signal-backed so thevalid/finishButtonTextcomputeds don't freeze against an undefined child.ngAfterViewInitinto ViewChild setters,KubeConfigHelperlifted to the wizard so parsed clusters survive step transitions, parent-ownedapplyStartedsignal replaces cross-step template binding and frozen computeds.make test frontend PROJECT=<project> SCOPE=<path>for narrowed vitest runs.Verification
make check gategreen.enterDataafter the activating render.