Skip to content

Workstream B wave 1: 5 signal-native page migrations#5323

Merged
norman-abramovitz merged 9 commits intocloudfoundry:developfrom
nabramovitz:feature/b-workstream-wave-1
May 11, 2026
Merged

Workstream B wave 1: 5 signal-native page migrations#5323
norman-abramovitz merged 9 commits intocloudfoundry:developfrom
nabramovitz:feature/b-workstream-wave-1

Conversation

@nabramovitz
Copy link
Copy Markdown
Contributor

Summary

Five parallel signal-native consumer migrations from Workstream B. Each replaces the legacy ngrx-paginator/cfEntityCatalog pattern with the established *-signal-config service + signal component pattern.

  • B1.2 Org summary — delete flow swapped from entityCatalog.getEntity + selectDeletionInfo + RouterNav dispatch to CfOrgsSignalConfigService.deleteOrg(...) + router.navigate. Service method already existed (org wall).
  • B1.4 Space summary — mirror of B1.2, uses CfSpacesSignalConfigService.deleteSpace(...) (already shipped with org-spaces L5).
  • B5.2 Add-route — drops the last Store + cfEntityCatalog.space.store.getEntityService include-chain in the add-route stepper. Domain list now reads applicationService.orgDomains$ via toSignal. Domain shape is the develop-current flat StDomain (not the legacy APIResource<IDomain>).
  • B6.1 Cells page — frontend-only rewrite over the existing /pp/v1/metrics/cf/cells/query passthrough. New CfCellsSignalConfigService with HEALTHY → HEALTHY_DEPRECATED probe fallback (Diego v2.31+ vs older) and a tri-state availability() signal replacing the legacy hasCellMetrics$ Observable gate. Legacy cloud-foundry-cells.component + cf-cells-list-config.service + cf-cells-data-source deleted.
  • B4.2 Variables tab — drops IListConfig + cfEntityCatalog.appEnvVar + the legacy appService.appEnvVars paginator. New CfAppVariablesSignalConfigService derives the var list from AppDetailDataService.envVars(). New AppVariableActionsService owns add/update/delete via PATCH /pp/v1/cf/apps/{cnsi}/{app} with merged environment_json (matches legacy AppVariablesUpdate semantics).

No shared infra changes — CfOrgsSignalConfigService.deleteOrg and CfSpacesSignalConfigService.deleteSpace already existed; AppDetailDataService.envVars() already exposed the read signal needed.

Test plan

  • bunx tsc --noEmit -p packages/cloud-foundry/tsconfig.lib.json clean
  • Vite dev-server bundle generation clean
  • Live verify on adepttech CF (Playwright):
    • Variables tab renders, list pulls from envVars signal, Add Variable button present, no console errors
    • Org summary renders with org name from StOrg.name, Delete button present, no console errors
    • Cells page mounts new CloudFoundryCellsSignalComponent and renders the legacy "metrics not found" empty state when the firehose endpoint isn't deployed (correct tri-state)
  • Full make check gate — to be batched with subsequent B-wave PRs

Notes

  • The original add-route commit was written assuming the pre-Workstream A wrap-up: app-detail native handlers + apps OrgGUID #5322 envelope-shape orgDomains$. After rebase onto develop (which merged Workstream A wrap-up: app-detail native handlers + apps OrgGUID #5322), a fixup commit flips it to the flat StDomain shape. Will be squashed on merge.
  • Inline edit-in-place (legacy TableCellEditVariableComponent) is dropped from the Variables tab in this slice; actionsService.updateVariable is wired so a re-prefilled Add form would restore that affordance — small follow-up.
  • Cell-detail sub-routes (cells/:cellId/{summary,charts,apps}) still use the legacy CloudFoundryCellService / ngrx path. Not in this slice's scope; would be a follow-up alongside the broader cells deep-dive.

Drops Store + entityCatalog.getEntity + selectDeletionInfo +
RouterNav dispatch. Delete confirm now awaits
CfOrgsSignalConfigService.deleteOrg(cfGuid, orgGuid) — the same
signal-native write path used by the org wall — then router.navigate
back to the orgs list. Errors surface via TailwindSnackBarService.

The deleteOrg method already existed on the signal-config service
(shipped with the org wall). No shared infra changes.
Mirror of the org-summary migration. Drops Store +
entityCatalog.getEntity + selectDeletionInfo + RouterNav dispatch.
Delete confirm now awaits CfSpacesSignalConfigService.deleteSpace(
cfGuid, spaceGuid) — already shipped with the org-spaces L5
migration — then router.navigate back to the org-spaces list.

deleteSpace hits DELETE /pp/v1/cf/spaces/:cnsiGuid/:spaceGuid via
writeWithJob (async-job polling) then refresh(). No shared infra
changes.
Finishes the partial signal migration of the add-route stepper.
Removes Store<CFAppState> injection plus the two RouterNav dispatch
calls (replaced with inject(Router) + router.navigate). Drops
cfEntityCatalog.space.store.getEntityService include-chain — the
domain list now reads applicationService.orgDomains$ via toSignal.
The space_guid the legacy chain side-effected is now captured by a
small waitForAppEntity$ subscription.

Domain auto-pick (first domain) is guarded so a later orgDomains$
re-emit can't clobber a user pick. Spec drops Store + RouterNav
mocks, spies on Router.navigate from provideRouter.
Cells data is Diego cell rep-health metrics scraped from the
firehose, not a CF v3 resource. Backend metrics endpoint
(/pp/v1/metrics/cf/cells/query) was already in place — this is a
frontend-only migration.

Adds CfCellsSignalConfigService owning the Prometheus query with
HEALTHY -> HEALTHY_DEPRECATED probe fallback (Diego v2.31+ vs older)
and a tri-state availability() signal that replaces the legacy
hasCellMetrics$ Observable gate. Adds CloudFoundryCellsSignalComponent
mirroring the cf-stacks signal pattern. Route swap in
cloud-foundry-section.routes.ts.

Legacy cloud-foundry-cells.component + cf-cells-list-config.service
+ cf-cells-data-source deleted (no remaining consumers; cell-detail
sub-routes still use CloudFoundryCellService and are out of scope).
Migrates the app-detail Variables tab from the legacy IListConfig +
ngrx Store dispatch pattern to signal-native. The new
CfAppVariablesSignalConfigService derives a Signal<ListAppEnvVar[]>
from AppDetailDataService.envVars().environment; the new
AppVariableActionsService owns add/update/delete writes that PATCH
/pp/v1/cf/apps/{cnsi}/{app} with the merged environment_json map
(matching the legacy AppVariablesUpdate semantics).

The component drops IListConfig + Store + cfEntityCatalog.appEnvVar
+ the legacy appService.appEnvVars paginator. Delete row action
goes through a confirm dialog. Inline Add form preserved with
on-submit validation; on save it calls actionsService.addVariable
then dataService.refresh('envVars').

Inline edit-in-place (TableCellEditVariableComponent) is dropped
in this slice; updateVariable is wired and a re-prefilled Add form
would restore that affordance — follow-up. Legacy
cf-app-variables-list-config.service + data-source files are now
dead code, kept in tree for now.
PR cloudfoundry#5322 merged the orgDomains$ type flip from
Observable<APIResource<IDomain>[]> to Observable<StDomain[]> and
the wrapDomain shim was deleted. This branch's add-route commit
was written before that merge per the original brief.

Updates the add-route component's domain reads to the flat shape:
- domain.metadata.guid -> domain.guid
- domain.entity.router_group_type === 'tcp' ->
  domain.supportedProtocols?.includes('tcp') ?? false
- Drops APIResource + IDomain imports; uses StDomain throughout.
@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla Bot commented May 11, 2026

CLA Not Signed

PR CI caught two leftovers from the wave-1 rebase:

- Template's TCP/HTTP branching read selectedDomain?.entity?.router_group_type
  (the v2 envelope path); now reads selectedDomain?.supportedProtocols?.includes('tcp').
- Spec mocks built domain values as { metadata, entity } envelopes; now
  build them as flat StDomain { guid, supportedProtocols }.

Local vitest run passes 16/16 add-routes tests.
Mirrors the done space-users migration. Adds an org-scoping mode
to CfUsersSignalConfigService (initializeForOrg + _lockedOrgGuid
signal); the users computed filters to users with at least one
org-role bucket OR one space-role bucket carrying the target
orgGuid. Precedence: space lock > org lock > unscoped.

Component drops the legacy CfOrgUsersListConfigService provider
plus the ngrx-paginator pipeline (addRolesByUsernameLink$,
ListComponent, NoContentMessage, PageSubNav, CfAdminAddUserWarning,
CloudFoundryInviteUserLink imports). Renders 5 columns: Username,
Origin, Org Roles for THIS org, Space Roles narrowed to spaces
under THIS org, Created. Template now app-list-sub-nav +
app-signal-list.

Legacy cf-org-users-list-config.service + spec deleted (no
remaining consumers). Spec rewritten to assert initializeForOrg
called with cnsi+orgGuid and column shape narrowing.
Component had eight Observable<boolean> fields (connecting$, valid$,
isBusy$, etc.) declared but never assigned — the | async pipes in
the template were always undefined, so the loading bar / error
banner / submit-disable were effectively static.

Rewritten to actually drive UI state: signal()s for showSecret,
isBusy, hasErrored; toSignal(form.statusChanges) for formStatus;
computed() for formValid + canSubmit. submit() now toggles
busy/error state during the configure call and surfaces failures
via sticky red snackBar.error().

Template drops | async pipes for signal calls; show-secret toggle
moves to a method; Cancel button gets type="button" so it doesn't
accidentally submit; submit button binds [disabled]="!canSubmit()".

UserInviteService public surface unchanged — left alone since it
was already clean (HttpClient, no Store/ngrx coupling) and has
multiple downstream consumers.
Copy link
Copy Markdown
Contributor

@norman-abramovitz norman-abramovitz left a comment

Choose a reason for hiding this comment

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

The PR hopefully covers the remaining stratos-to-backend-to-capi v3 conversion, and the front is 90% using Angular 21 signals instead of observables. The next PR does the auditing and removes the V2 frontend shims.

@norman-abramovitz norman-abramovitz merged commit 38b5a73 into cloudfoundry:develop May 11, 2026
11 of 12 checks passed
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.

2 participants