Skip to content

CF Users: multi-org role-assignment widget, space_supporter, and a role registry - #5479

Merged
norman-abramovitz merged 33 commits into
cloudfoundry:developfrom
nabramovitz:feature/cf-users-phase4-role-widget
Jun 22, 2026
Merged

CF Users: multi-org role-assignment widget, space_supporter, and a role registry#5479
norman-abramovitz merged 33 commits into
cloudfoundry:developfrom
nabramovitz:feature/cf-users-phase4-role-widget

Conversation

@nabramovitz

Copy link
Copy Markdown
Contributor

Replaces the single-org "keyhole" in Manage Roles and Add User with a multi-org accordion widget: searchable org multi-select, per-org expand/collapse with an "N roles set" summary, and tri-state role checkboxes across org and space scopes. Adds the space_supporter role end to end — backend read, list display, the assignment widget, and the connected user's own self-read.

Role facts now come from a single ROLE_DEFS registry. The CF v3 type and display labels are derived; only the irregular relation-bucket and permission columns are enumerated. Six previously-hardcoded sites (type conversion, permission mapping, labels, relation tables, widget defs, entity schema) derive from it, so adding a role is one entry instead of ~10 edits.

Space-role cells now gate on per-space SPACE_CHANGE_ROLES, so a space manager can manage their own space's roles without being an org manager; the org picker no longer dead-ends them. Org-role cells remain org-manager gated.

Removes three components orphaned by the widget swap. Test coverage moves the three host specs onto the real widget via a shared harness, including a regression test for the empty-grants path.

Gate green: 2804 frontend tests, prod build, all Go.

Backend: add space_supporter→supported_spaces to roleTypeToBucket and
spaceBucketKeys so the /v3/roles response populates the supported_spaces
bucket that the FE CfUser.supported_spaces field reads.

Frontend: wire SUPPORTER into SPACE_ROLE_TABLE (post-processor),
UserRoleLabels (short: Supporter / long: Space Supporter), and
coreSpaceSchemaParams (entity factory) mirroring developer/auditor
entries. Tests extended: Go happy-path + new IncludesSpaceSupporter case;
FE post-processor mirrors-space-roles updated + dedicated supporter test.
Add CfPermissionStrings.SPACE_SUPPORTER = 'isSupporter', add
isSupporter to ISpaceRoleState + defaultCfUserSpaceRoleState,
wire case SpaceUserRoleNames.SUPPORTER in roleNameToPermission,
and include isSupporter in the spaceGuids removal guard.

Fixes TS2366: non-exhaustive switch after SUPPORTER was added
to SpaceUserRoleNames.
…ters render checked

spacePermissionsFromRoles passed only 3 args to createUserRoleInSpace,
leaving the 4th supporter param undefined. Backend delivers the role as
the stripped singular string 'supporter'; pass roles.includes('supporter')
as the 4th arg, mirroring the existing manager/auditor/developer pattern.

Also add stIsSpaceSupporter predicate and cover all three paths in spec.
Replace the all-spaces endpoint drain plus client-side filter with a
per-org /pp/v1/cf/org/{cf}/{org}/spaces fetch (jetstream getNativeOrgSpaces,
organization_guids filter). Cache per org via shareReplay without refCount so
re-expanding a section reuses the result instead of re-draining ~2500 spaces.

Updates the cf-roles.service specs from the old all-spaces URL to the per-org
endpoint.
Live-verify gaps the unit suite missed:

- Seed the accordion from the baseline's existing-role orgs on open (effect
  guarded by baselineSeeded), so current roles show without re-picking each org.
- Derive the collapsed per-org role count from baseline + selection rather than
  loaded spaces, so summaries are accurate with zero space fetches.
- Lazy-load each org's spaces on first expand; prepend newly picked orgs.
- Add org-list and per-section loading spinners (loading input driven by the
  host's existingRoles$ resolve).
- Apply Tailwind styling matching the stepper (bg-content-bg-alt surfaces,
  primary accents, bounded scrollable picker, carded accordion); preserve all
  data-testids and BEM hooks the specs rely on.
Add a Users breadcrumb on the manage-users page header (renders
Users > Manage Roles) and pass the existingRoles$ loading state plus per-org
inputs through to the role-assignment widget so its spinner reflects the host's
resolve.
Replace require('rxjs') calls in the lazy-load test with the top-level of
import; require-style imports trip @typescript-eslint/no-require-imports and
failed the lint gate.

@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 9223efd into cloudfoundry:develop Jun 22, 2026
12 checks passed
@nabramovitz
nabramovitz deleted the feature/cf-users-phase4-role-widget branch June 22, 2026 02:12
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