Skip to content

Wave CDEF: signal-native ngrx cleanup, mutation-refresh, fw-capi async-delete#5362

Merged
norman-abramovitz merged 24 commits into
cloudfoundry:developfrom
nabramovitz:feature/wave-cdef-cf-ngrx-cleanup
May 23, 2026
Merged

Wave CDEF: signal-native ngrx cleanup, mutation-refresh, fw-capi async-delete#5362
norman-abramovitz merged 24 commits into
cloudfoundry:developfrom
nabramovitz:feature/wave-cdef-cf-ngrx-cleanup

Conversation

@nabramovitz
Copy link
Copy Markdown
Contributor

Summary

Umbrella branch covering four interlocking workstreams that prepare Stratos for full V3-native CF data access and retire the remaining ngrx coupling in the cloud-foundry package.

1. Wave 4 ngrx cleanup (W-a .. W-f)

Removes ngrx Store/effects/selectors from six remaining surfaces that the earlier waves left behind. Each slice retires its V2 ngrx code while a signal-native replacement carries the traffic.

  • W-a Signal-native metrics — replaces the V2 metrics chart layer and 7 consumers; deletes the V2 ngrx metrics surface.
  • W-b Apps wall — retires CfAppsDataSource in favour of direct EndpointDataService signal reads.
  • W-c CF user — swaps the isConnectedUserAdmin selector to read the signal-native cnsi-user snapshot.
  • W-d Application updates — retires the V2 update-app effect.
  • W-e CF info — swaps an effect for an EndpointDataService fetcher.
  • W-f Endpoint-data shim — retires V2 org/space paths through the shim.

2. EDS mutation-refresh architecture (Phase 1-3)

After every write (create / update / delete) the relevant cached list now invalidates immediately instead of waiting for a hard reload.

  • Phase 1 EndpointDataService staleness signals + a cascade registry; refreshX and applyCascade entry points.
  • Phase 2 New CnsiOrgsSource + CnsiSpacesSource; SI / SB / Routes / Apps sources retrofitted with writeWithJob + EDS patch + applyCascade.
  • Phase 3 Signal-list configs for orgs / spaces / apps wired to sources; cloud-foundry-endpoint.fetchApps flipped from loadDetails to refreshDetails (closes the silent refresh-button no-op).
  • Bypass migration Eleven steppers + the app-detail PATCH that previously called http.post/patch/delete directly now route through their CnsiXSource so the canonical cache patches in place and the cascade verb fires.

3. fw-capi v3.216.4-fix-apps-delete.11

Extends the Location-header parser across nine v3 delete handlers (orgs, spaces, domains, users, security_groups, brokers, service_instances, route_bindings, buildpacks). Pure CAPI-client plumbing; the jetstream-side wiring still uses writeWithJob.

4. UX + quality-of-life

  • 4-tab Org+Space filter dropdowns on Routes, Services, Users, and Events.
  • All-orgs Space dropdown labels space-plus-org with natural sort.
  • Refresh-button spinner now engages on endpoints, k8s, org-quotas and space-quotas pages.
  • CF Summary CLI Info icon swapped to a material-icons terminal glyph.
  • FWT-929 duplicate-URL warning restored on the endpoints page via kind:'template'.

Merge strategy

This PR is intentionally a stack of small slices. Please Create a merge commit rather than squash or rebase so the slice identity stays in history — squashing a 23-commit slice stack destroys the ability to bisect inside the umbrella.

Test plan

  • make check lint — 0 errors (109 pre-existing warnings)
  • make check tests for the cloud-foundry project — 1167 passed, 1 skipped, 0 failures
  • Dev.97 deployed and exercised on adepttech for the delete flow + 4-tab dropdowns
  • Local hot-reload validation of the 11 bypass-site fixes pending against the running dev server

Introduce MetricsDataService — a signal-native HTTP client for CF
metrics that replaces the V2 MetricsAction / EntityServiceFactory /
EntityMonitor wire. Exposes a one-shot fetch(req) and a signal-bound
observe(requestSignal, { pollIntervalMs }) that returns
{ metrics, fetching, error, refresh, stop } signals.

Pattern-setter for B1 PR-A1: chart components + range selectors + 4
consumers move to MetricsRequest signals in subsequent commits of this
wave. cf-metrics.actions.ts and metrics.effects.ts stay for now;
PR-A2 deletes them once all V2 consumers are gone.
Refactor MetricsChartComponent, MetricsRangeSelectorComponent,
MetricsParentRangeSelectorComponent and the range-selector services
to consume Signal<MetricsRequest> via MetricsDataService.observe()
instead of dispatching MetricsAction objects through the V2 ngrx
METRICS_START effect + EntityMonitor wire.

Chart owns a writable requestSignal; ContentChild range selector
emits a MetricsRequest output that the chart applies to the signal;
parent range selector mutates each child chart's signal via the
new chart.applyRequest() seam.

Migrated 7 consumers off MetricsAction construction:
  - cf:  metrics-tab, application-instance-chart,
         cloud-foundry-cell.service, cf-cell-apps-signal-config
  - k8s: pod-metrics, kubernetes-node-metrics,
         kubernetes-node-metrics-chart

cloud-foundry-cell.service now picks the live health-metric (HEALTHY
vs HEALTHY_DEP) by direct fetch-and-check instead of the CfCellHelper
ngrx pagination probe.

Also:
  - drop dead <app-metrics-range-selector> block from list.component
    (showCustomTime is set false everywhere; V2 list framework)
  - MetricsDataService.observe() anchors effect() to the service's
    captured injector via runInInjectionContext so callers from
    ngOnInit (not themselves in an injection context) work
  - update 2 inline-mocked specs (cloud-foundry-cell-charts/-summary)
    for the MetricsConfig.request field rename

cf-metrics.actions.ts, metrics.effects.ts and kubernetes metrics
actions are now dead code; PR-A2 deletes them.
Now that the chart layer + 7 consumers are off MetricsAction, strip the
dead V2 wiring end-to-end:

Live consumer migrations:
  - KubernetesNodeService.setupMetricObservable now drives the node
    stats cards via MetricsDataService.observe() with a 30s poll;
    drops MetricsAction + EntityMonitor + store.dispatch.
  - CloudFoundryCellBaseComponent's "wait for cell metric" gate is
    derived from cellMetric$ readiness (Observable<boolean>) instead
    of LoadingPage's V2 entityId/entitySchema entity-monitor path.

Effect + helper deletions:
  - cf-metrics.actions.ts (FetchCF*Metrics*, FetchApplication*Metrics*)
  - cf-cell.helpers.ts (CfCellHelper — pagination-based health-metric
    probe; replaced by direct fetch-and-check in cloud-foundry-cell
    .service)
  - cf-app-instances-metrics-action.ts helper
  - app.effects.ts:clearCellMetrics$ (post-scale-up immediate refresh;
    chart's 10s poll picks up the change instead — same end state ~10s
    later)
  - metrics.effects.ts (METRICS_START handler) + store.module wiring
  - FetchKubernetesMetricsAction + FetchKubernetesChartMetricsAction
  - MetricsAction + MetricsChartAction base classes + METRICS_START*
    constants in metrics.actions.ts (kept MetricQueryConfig and
    getFullMetricQueryQuery which MetricsRequest still uses)

Entity-catalog cleanup — metricEntityType registrations are dead now
that nothing dispatches MetricsAction:
  - stratos-entity-factory (const + base schema)
  - cf-entity-factory + cf-entity-generator.generateCFMetrics
  - kubernetes-entity-factory + kubernetes-entity-generator
    .generateMetricEntity
  - autoscaler-entity-factory + autoscaler-entity-generator
    .generateMetricEntity
  - public-api re-export

V2 list-framework metrics path (verified dead — no consumer set
showCustomTime=true):
  - drop metricsAction field + updateMetricsAction method from
    list-data-source + interface
  - drop showCustomTime / customTimeWindows /
    customTimeInitialValue / customTimePollingInterval /
    customTimeValidation from list config
  - drop handleTimeWindowChange hook

Spec updates:
  - cell-base.spec: HttpClientTesting + override component-level
    CloudFoundryCellService provider with the existing mock
  - cell-summary.spec: drop healthyMetricId from mock
  - metrics-chart.spec: drop dead-code commented FetchApplication ref
The apps-wall page is already signal-native (CfAppsSignalConfigService);
the V2 CfAppsDataSource only survived because two stepper components
still round-tripped through ngrx pagination state to discover the
wall's currently-selected cf/org/space when the user navigated
"+ Create Application" or "+ Deploy Application" from the wall.

CfAppsSignalConfigService is providedIn: 'root', so its
selectedCnsi / selectedOrg / selectedSpace signals persist across
the route change. The steppers now read those signals directly:

  create-application: ngOnInit
  deploy-application: ngOnInit else-branch (no appGuid path)

Drops:
  - cf-apps-data-source.ts (126 lines — the V2 data source that
    dispatched GetAllApplications + CreatePagination + per-row
    appStats fetches; entire chain is dead since the wall stopped
    using it)
  - paginationStateSub + selectCfPaginationState wire in create
  - entityKey + selectPaginationState wire in deploy

Behavior preserved one-for-one: create-application keeps its
`cf && org` / `cf && org && space` precondition gating; deploy
keeps its independent cf/org/space assignments.
cf-user.service.isConnectedUserAdmin was the only direct ngrx
selector consumer in this file outside the V2 list-framework
pagination cache path. Swap it for the existing signal-service
facade (CfCurrentUserRolesSignalService.cfEndpointRolesState$),
which returns the same role-state shape without touching Store.

The wider `createPaginationAction` rewrite (line ~366,
selectCfPaginationState) is deferred — it has 3 live consumers
(cf-admin-add-user-warning, org-base, space-base) that each switch
on the returned action shape, and the V2 "is-maxed" semantics
don't translate cleanly to CfUsersSignalConfigService yet.
Delete UpdateAppEffects and drop its registration from the cloud-foundry
store + test modules. The effect listened for CF_APP_UPDATE_SUCCESS and
dispatched fanout actions (env vars, stats, summary) so the V2 ngrx app
cache stayed coherent after a mutation.

No live consumer dispatches UpdateExistingApplication anymore; the
edit-application step now calls AppDetailDataService.update() (PATCH
/pp/v1/cf/apps/:cnsi/:guid) which already refreshes the app entity, and
the component itself triggers detail.refresh('stats') after a scale.
Env vars / summary are owned by the same signal-native service. The
post-scale-up metrics refresh that lived in app.effects.ts:clearCellMetrics
was already retired in W-a4, so the entire ngrx fanout is dead code.

The CF_APP_UPDATE_SUCCESS action type and UpdateExistingApplication
class are left in place — they remain referenced by the entity-catalog
action-builder registration (cleanup belongs to a later wave that
retires the application entity action surface).
W-e of the ngrx-removal sweep. cfInfo was the only handler in
CloudFoundryEffects — the V2 action listener dispatched GetCFInfo,
hit /pp/v1/cf/info/{guid}, and wrapped the response in the legacy
WrapperRequestActionSuccess/Failed envelope for the request reducer.
The signal-native CfInfoDataService already covers the same fetch
(introduced in a prior wave) and is the live source for every
visible consumer (CloudFoundryEndpointService.info$, card-cf-info,
endpoint summary header). The effect was kept alive only by the
EndpointHealthCheck callback in cf-entity-generator dispatching
cfEntityCatalog.cfInfo.api.get(endpoint.guid).

Migration:

  * Added CfInfoDataService.refresh() — bypasses the warm-cache
    short-circuit so the health-check pulse still produces a fresh
    HTTP fetch (load() would otherwise short-circuit forever once
    warm). In-flight dedup still applies.
  * Added cf-info-helper.ts with a module-level injector capture
    (same pattern as autoscaler-available.ts) so the static
    healthCheck lambda can reach CfInfoDataRegistry without an
    Angular injection context.
  * Wired setCfInfoHelperInjector(inject(Injector)) into the
    CloudFoundryPackageModule constructor.
  * Rewired the CF endpoint healthCheck callback to call
    refreshCfInfo(endpoint.guid) instead of dispatching GetCFInfo.

Deletions (now fully orphaned):

  * store/effects/cloud-foundry.effects.ts (only effect in the file)
  * actions/cloud-foundry.actions.ts (GET_CF_INFO + GetCFInfo only)
  * entity-action-builders/cf-info.action-builders.ts
  * generateCFInfoEntity() and the cfEntityCatalog.cfInfo registration
  * cfInfoEntityType constant + CFInfoSchema entry
  * CloudFoundryEffects registrations from cloud-foundry.store.module
    and cloud-foundry-test.module.
  * cfInfoEntityType from public_api.ts (not referenced externally).

The /pp/v1/cf/info/{cnsi} wire path is unchanged; the V3-only
Stratos-native handler still returns the legacy ICfV2Info shape,
just now consumed directly by CfInfoDataService instead of being
dispatched through the request-pipeline reducer.
Remove the WrapperRequestActionSuccess dispatch paths for orgs and
spaces from EndpointDataShim. Earlier waves retired every consumer of
the pagination state the shim used to populate:

- cfEntityCatalog.org/space.actions.getMultiple readers are gone;
  cloudfoundry-endpoint.service.orgs$ now sources from
  EndpointDataService.orgs() (W-b path).
- CfOrgSpaceDataService fetches orgs/spaces directly via HTTP into its
  own signal state rather than reading the entity catalog pagination
  store.
- selectCfEntity(organizationEntityType / spaceEntityType, guid) reads
  by bare guid, while the shim wrote under FWT-934 composite keys
  (cnsiGuid:guid), so even single-entity selectors didn't pick up the
  shim's writes.

What was removed:
- dispatchOrgs(): action = cfEntityCatalog.org.actions.getMultiple +
  WrapperRequestActionSuccess under paginationKey 'endpoint-{cnsi}'.
- dispatchSpaces(): action = cfEntityCatalog.space.actions.getMultiple
  + WrapperRequestActionSuccess under paginationKey 'spaces-bulk-{cnsi}'.
- detectCollisions(): store.select probe of state.request[entityKey]
  to count entity-key-collision-avoided events; its observability
  value was tied to the write path being live.
- Inline toOrgResource/toSpaceResource builders (StOrg->APIResource
  envelope is now only needed by st-org-adapter.ts for the
  cloudfoundry-endpoint.service bridge — kept there, not duplicated).

What stays in place:
- write() still emits entity-size-sample diagnostics per org and per
  space, now sampling the StOrg/StSpace payload directly instead of
  the APIResource envelope.
- EndpointDataService.loadDetails().finalize() still calls shim.write()
  — consumer-side removal is a separate scope.

Spec updated to assert the new behavior: no dispatches, diagnostics
samples only, apps still stay out of the shim.
Tests 1-4 of duplicate-url-collision.spec.ts asserted on dispatched
WrapperRequestActionSuccess actions emitted from EndpointDataShim.write().
W-f retired all such dispatches, so those assertions can no longer pass.
Test 5 (cfEntityId composition) is redundant with cf-entity-ref.spec.ts.
The integration/ directory is empty after removal.
The signal-list migration (28d183f, ef8cd15) rebuilt the Address
column as plain text and dropped the warning icon FWT-929 had wired up
(cfe9fb3). TableCellEndpointAddressComponent — with its existing
isDuplicate$ logic — is still in the tree, just orphaned.

Restore it via the framework's existing kind:'template' mechanism plus
a projected <ng-template appSignalListCell="address"> at the consumer
site. The signal-list framework stays domain-agnostic; the endpoints
page owns its cell choice. If a second consumer ever needs the same
duplicate-URL cell, both share the component directly — no framework
growth required.
Picks up the Location-header parse fix extended across all 9 delete
handlers (orgs / spaces / domains / users / security_groups / brokers
/ service_instances / route_bindings / buildpacks). Stratos issues the
async-job delete envelope on those resources; without the upstream
fix the 202 job ref was lost in the response wrapper, causing the
client to spin without a terminal state.

The `replace` directive still points at norman-abramovitz/fw-capi
until the fix lands on the fivetwenty-io fork's tagged release.
Phase 1 of the mutation-refresh architecture. The post-Wave-3 signal
migration left every mutation's "refresh the affected pages" path on
ad-hoc per-page logic — silently broken in several cases (org delete
not repainting, refresh button no-op, snackbar flash). Plumbs the
generic foundation here so Phase 2 (source classes) and Phase 3
(SignalListConfig wiring) have something to dispatch into.

EndpointDataService gains:
- _orgsStale / _spacesStale / _appsStale / etc. signals + readonly
  accessors. The cache-predicate in loadDetails / loadOrgs / loadApps
  / loadSpaces now considers staleness alongside lastFetched, so the
  next read after a mutation re-fetches even when the cache is warm.
- 14 patch helpers (removeOrg/addOrg/updateOrg + same for spaces /
  apps / SI; remove/addServiceCredentialBinding) so source classes
  can update the canonical cache atomically with each write.
- markStale(entity), applyCascade(key), refreshOrgs/refreshApps/
  refreshSpaces/refreshDetails — the entry points sources call after
  a mutation lands.

cascade-registry.ts declares the cross-entity staleness rules in one
typed map (org.delete → [spaces, apps, serviceInstances, bindings];
space.delete → [apps, SI, bindings]; etc.). The "what should this
mutation invalidate" question becomes a one-line lookup instead of
re-deriving it at every callsite. cascadeFor(key) is the only
external entry — sources call applyCascade(key) which delegates here.

DIAGNOSTIC_CODE_FAMILIES gains the 'cascade-apply' enum value so
applyCascade emissions surface in the diagnostics tab.
Thin mutation surfaces over /pp/v1/cf/organizations/{cnsi} and
/pp/v1/cf/spaces/{cnsi}. Each source extends CnsiEntitySource and
exposes create/update/delete that:
1. Issues the HTTP write (delete goes through writeWithJob so CF's
   async 202 → /v3/jobs/{guid} terminal state is honoured).
2. Patches its own _items via patchItems (so consumers reading the
   source's items() signal repaint immediately).
3. Calls into EndpointDataService's matching patch helper (add/
   remove/update Org or Space), keeping the canonical cache aligned.
4. Fires applyCascade('org.delete' | 'org.create' | 'space.delete'
   | 'space.create' | ...) to mark dependent entities stale per the
   cascade-registry rules.

These two were missing — orgs and spaces were the entities most often
mutated by the user-facing flows (Add Org, Delete Org, Add Space,
Delete Space), and the Wave-3 migration retired their ngrx effects
without ever wiring a replacement repaint trigger. Sources here fill
that gap.
Brings the four pre-existing mutation sources up to the contract that
the new orgs / spaces sources established:

CnsiServiceInstancesSource — gains create/update/delete; existing
write path moves to writeWithJob; EDS patch + applyCascade fires
on terminal state.

CnsiServiceBindingsSource — retrofitted to use the canonical
StServiceCredentialBinding from stratos-types (had a local
StServiceBinding placeholder that didn't carry type / serviceInstance
/ createdAt). The new EDS addServiceCredentialBinding signature would
not type-check against the placeholder.

CnsiRoutesSource — delete now goes through writeWithJob + patchItems
+ EDS patch + applyCascade('route.delete') so the apps cascade-stale
fires (app-detail routes lists were the silently-broken consumer).

CnsiAppsSource — applyCascade calls added for app.delete, app.update,
route.create. The eds ctor arg is optional so existing tests don't
break.

cnsi-routes-source.spec.ts + cnsi-service-bindings-source.spec.ts
updated to assert the new contract (HttpResponse mock + writeWithJob
flow). cnsi-service-instances-source.spec.ts is new.
…ase 3)

Pulls the orgs / spaces / apps SignalListConfig services off their
ad-hoc mutation paths and onto the new CnsiOrgsSource / CnsiSpacesSource
contracts. Each config now:

- Instantiates the source once per initialize() (sharing EDS via
  the registry), caching it for subsequent mutations on the same CF.
- Routes delete (and create/update where exposed) through the source,
  so the cascade fires once and EDS patches itself.
- refresh() now calls EDS.refreshOrgs / refreshApps / refreshSpaces
  (which bypass the cache predicate) instead of loadDetails — which
  short-circuited on cache hit, leaving the user-facing refresh button
  a no-op.

CloudFoundryEndpointService.fetchApps() flips from loadDetails to
refreshDetails for the same reason — fetchApps is the "polling
indicator clicked / page-level refresh" entry point.
…bars

isAnyLoading on both toolbars was wired to a hardcoded signal(false),
so the refresh button's spinner never engaged on either page. Pipe in
the real EndpointsDataService.loading signal so clicking refresh shows
the spinner while getAll() drains, matching the cf-services / cf-apps
behaviour.

The endpoints-page config exposes the loading signal via a `loading`
readonly accessor; the k8s-endpoints config reads its EndpointsDataService
directly (already injected for the endpoints projection). Same change
shape so the two pages stay in sync.
The page-sub-nav CLI Info button rendered a `keyboard` glyph, which
reads as "key input" rather than "open a terminal session." Material
Icons' `terminal` glyph is the conventional choice for CLI affordances.
One-line cosmetic.
…Events

Apps wall already exposed CF / Org / Space dropdowns; the rest of the
CF navs that have org/space membership had no parallel — users couldn't
narrow Routes / Services / Users / Events without leaving the page.

Each affected config service gains:
- selectedOrg / selectedSpace WritableSignals (null = "All").
- orgOptions / spaceOptions computed lists, sorted natural-order
  (numeric-aware), "All" first.
- A filter-effect clause that drops rows whose org/space don't match.
- A cascade effect that clears selectedSpace when selectedOrg switches
  to a different specific org (the stale space is no longer reachable
  through that org). Org → All preserves the space selection.

Space dropdown labels are cascade-aware:
- Org selected → label is the space name on its own.
- Org = All → label is "<space> - <org>" so the picker disambiguates
  identical space names across orgs (typical CF naming has many
  "dev" / "prod" spaces). Sort order: space name natural-sort, then
  org name natural-sort within the collision group.

Per-page consumers (cf-services, cf-users, services-wall, cf-routes,
cf-events-list) get the new dropdowns wired into their SignalListConfig
filterDropdowns slot. cf-events-list conditionally renders them only
on the foundation-wide page — the per-org / per-space / per-app
sub-pages pin scope via basePredicate and elect to omit dropdowns
that would let the user pick mismatched values.

Service-instances config is multi-CNSI, so the new dropdowns union
orgs / spaces across the in-scope CNSIs (or narrow to the selected CF
when the CF dropdown is locked, as on per-CF tabs). EDS acquisition
inside computed()s would refcount-leak, so initialize / initializeForX
swap a tracked _edsByCnsi map through a refcount-balanced helper.

Specs updated to mirror the new stub shape: services-wall expects 3
dropdowns instead of 1; cf-users stub exposes orgOptions/spaceOptions/
selectedOrg/selectedSpace; cf-service-instances spec's FakeDs gains
orgs()/spaces() and the registry mock gains release().
Drops the four-tab Org+Space filter bundle + Phase 1-3 mutation
refresh + fw-capi .11 onto adepttech for browser verification.
Adds the all-orgs "space - org" labels + natural sort iteration on top
of dev.96 so the deployed environment matches the working tree.
Add create() to both sources so consumers can route app and route
mutations through the canonical EDS-patching path instead of raw
http.post. Each call patches the source items list, calls the
matching EDS patch helper, and fires the cascade verb (app.create
or route.create) so dependent surfaces invalidate.
…asses

Migrate every remaining direct http.post/patch/delete that targeted an
EDS-cached entity to its CnsiXSource so the canonical list cache patches
in place and the matching cascade verb fires. Eleven steppers + a per-app
detail-page PATCH now share the source-routing pattern.

  - create-organization-step          : http.post  -> CnsiOrgsSource.create
  - edit-organization-step            : OrgWriteService.updateOrg -> CnsiOrgsSource.update
  - create-space-step                 : http.post  -> CnsiSpacesSource.create
  - edit-space-step (name + SSH)      : http.patch -> CnsiSpacesSource.update
  - edit-space-step (quota detach)    : keeps raw http but fires space.update cascade
  - edit-space-step (quota attach)    : keeps raw http but fires space.update cascade
  - create-application-step3 (app)    : http.post  -> CnsiAppsSource.create
  - create-application-step3 (route)  : http.post  -> CnsiRoutesSource.create
  - app-detail-data.update            : http.patch -> CnsiAppsSource.update
  - detach-service-instance.detachOne : http.delete -> CnsiServiceBindingsSource.delete

Steppers now acquire/release the EndpointDataService on the registry so
the cache is alive for the duration of the write; for create-application
two acquires (app + route) are reference-counted and released on destroy.

Drops two dead routes that were already bypassed by the new sources:
OrgWriteService (no remaining callers) and the unused deleteSpace on
CloudFoundryOrganizationService (callers go through CfSpacesSignalConfig).
isAnyLoading on both quota tabs was tied to !hasLoadedOnce() so the
refresh-button spinner engaged only on the very first load. Add a
dedicated `loading` signal to each signal-config service that flips
true around load/refresh and read it directly from the components.
Matches the endpoints + k8s page fix already shipped this branch.
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.

more removal of ngrx and other fixes

@norman-abramovitz norman-abramovitz merged commit 3f5139c into cloudfoundry:develop May 23, 2026
12 checks passed
@nabramovitz nabramovitz deleted the feature/wave-cdef-cf-ngrx-cleanup branch May 23, 2026 07:08
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