CF Users: faster role load, view toggle, mixed-role summary, role-cell links - #5480
Merged
norman-abramovitz merged 5 commits intoJun 22, 2026
Conversation
For a multi-user selection the collapsed per-org badge counted only roles all users share, so an org where users hold divergent roles read as "0 roles set". Add mixedRoleCountForOrg (roles computeChecked marks indeterminate) and render "N set · M mixed" when any are partial; the single-user / fully-shared case keeps the existing "N roles set" text.
The picked-org editor now offers a two-pane master/detail layout alongside the stacked accordion, modeled on the list card/table toggle: a viewMode signal, a header toggle button, and the choice persisted to localStorage (stratos.role-assignment.view-mode.v1). The two layouts share one role-editor ng-template; switching reconciles the differing open-state (accordion can expand many orgs, split shows one active org) — entering split adopts the top picked org, returning to accordion expands only that org. Panes stack on narrow widths via CSS grid; lockedOrg stays accordion-only.
The /v3/roles include=space block already returns each space's name and parent org; capture both into one includedSpace map. StUserSpaceRole now emits spaceName alongside orgGuid/spaceGuid, resolved in-band with no extra request, so the role-assignment UI can label spaces without draining the whole /v3/spaces list.
populateRoles drained the entire /pp/v1/cf/spaces list (~2500 spaces, 6 pages) purely to map space guids to names — the dominant cost of the "Loading existing roles…" wait. StUserSpaceRole now carries spaceName, so spaceRolesFromStUser reads it from the bucket and the drain is gone; org names still come from the bounded native org list. Drops the now-unused fetchSpaces/cfSpaces cache.
The CF users-page org/space role cells stayed plain black text until the endpoint-data name maps loaded, then became links — yet the link target is built purely from guids that are present immediately. Gate the link on the guids instead of the resolved name, so the cell links from first paint and the label upgrades guid → name reactively. Space roles also read spaceName from the role payload (include=space) so the space name shows instantly rather than waiting for the /pp/v1/cf/spaces map.
norman-abramovitz
approved these changes
Jun 22, 2026
norman-abramovitz
left a comment
Contributor
There was a problem hiding this comment.
LGTM - Live verification
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.
Follow-up work on the CF Users role-assignment widget, after #5479.
Changes
Faster "Loading existing roles…" — the wizard drained the entire
/pp/v1/cf/spaceslist (~2500 spaces, 6 pages) only to map space guids to names. The/v3/roles?include=spaceresponse already carries each space's name, so the backend now emitsspaceNameon the role buckets and the frontend reads it from the payload. The drain is gone; the seed dropped from ~30s to ~2.5s in testing. Org names still come from the bounded native org list.Accordion / two-pane view toggle — the picked-org editor offers a two-pane master/detail layout alongside the stacked accordion, modeled on the list card/table toggle. A
viewModesignal, a header toggle, the two layouts sharing one role-editor template, and the choice persisted tolocalStorage. Switching reconciles the open-state (accordion can expand many orgs; split shows one active org). Panes stack on narrow widths; an org/space-scoped entry stays accordion-only.Mixed-role summary for multi-user — a multi-user org where users held divergent roles read as "0 roles set" because the badge only counted fully-shared roles. It now shows "N set · M mixed" when roles are partial.
User role cells link from first render — the org/space role cells on the users page stayed plain text until the name maps loaded, then became links, even though the link target is guid-based and available immediately. They now link from first paint and the label upgrades guid → name reactively; space roles also read the new payload
spaceNameso the name shows instantly.Testing
Full
make check gategreen (2823 frontend tests, backend package, production build). Each change was built test-first and live-verified on a real foundation via the dev backend (load time, no spaces drain, toggle, mixed badge, first-render links).