Skip to content

fix: deliver stepper onEnter after the activating render - #5604

Merged
norman-abramovitz merged 5 commits into
cloudfoundry:developfrom
nabramovitz:norm/fix/5600-specify-details-step
Jul 8, 2026
Merged

fix: deliver stepper onEnter after the activating render#5604
norman-abramovitz merged 5 commits into
cloudfoundry:developfrom
nabramovitz:norm/fix/5600-specify-details-step

Conversation

@nabramovitz

Copy link
Copy Markdown
Contributor

Closes #5600

Problem

SteppersComponent.setActive called pOnEnter synchronously after switching currentIndex, but step content is instantiated lazily by the ngTemplateOutlet on the next render. Every signal-handle onEnter that dereferences a @ViewChild of the entering step ran against undefined and was silently dropped.

In the bind-service wizard that meant formMode was 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

  • Stepper: pOnEnter delivery is deferred via afterNextRender (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.
  • specify-details-step / bind-apps-step: onEnter now runs outside change detection, and the step's first render has every @if false — template-bound fields written in onEnter are now signals (formMode, schemaFormConfig). The bind-apps hand-off also restores the plan schema driving the Binding Parameters editor.
  • create-endpoint / git-registration: registration result routed through submit's data channel to the connect handle's onEnter (the direct call at submit time ran before the connect child existed); connect ViewChild is signal-backed so the valid/finishButtonText computeds don't freeze against an undefined child.
  • kube-config-registration: bridges moved from ngAfterViewInit into ViewChild setters, KubeConfigHelper lifted to the wizard so parsed clusters survive step transitions, parent-owned applyStarted signal replaces cross-step template binding and frozen computeds.
  • Makefile: make test frontend PROJECT=<project> SCOPE=<path> for narrowed vitest runs.

Verification

  • Full make check gate green.
  • Live-verified on the dev stack: app → Bind Service → Marketplace → postgresql → cluster → Binding Params → Service Instance now renders the create form (mode radios correctly data-gated on existing instances).
  • New stepper spec pins delivery ordering: not synchronous, delivered with routed enterData after the activating render.
  • Not live-verified: kube-config import (needs the kind rig) and deploy-application filesystem deploys — both only receive the delivery fix plus mechanical rewiring; a live pass on those flows is worth doing before this leaves dev.

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
norman-abramovitz marked this pull request as ready for review July 8, 2026 17:38

@norman-abramovitz norman-abramovitz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@norman-abramovitz
norman-abramovitz merged commit d035f56 into cloudfoundry:develop Jul 8, 2026
18 checks passed
@nabramovitz
nabramovitz deleted the norm/fix/5600-specify-details-step branch July 8, 2026 20:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Binding marketplace service instance - Service instances not showing

2 participants