Skip to content

Show the user's TRE and workspace roles in the UI user menu - #5052

Draft
Jay W (JayDoubleu) wants to merge 1 commit into
microsoft:mainfrom
JayDoubleu:jaydoubleu/ui-user-role-indicator
Draft

Show the user's TRE and workspace roles in the UI user menu#5052
Jay W (JayDoubleu) wants to merge 1 commit into
microsoft:mainfrom
JayDoubleu:jaydoubleu/ui-user-role-indicator

Conversation

@JayDoubleu

Copy link
Copy Markdown
Collaborator

Resolves #5051

What is being addressed

The UI knows the roles of the user, but it does not show them. The core roles are
in AppRolesContext and the workspace roles are in WorkspaceContext. The
components that read them use them only to select which elements to show.

Thus two different conditions look the same. SecuredByRole removes an element
fully when the user does not have the role and the caller gives no error message.
A Researcher who does not see the "Create new" button cannot find the cause. The
cause can be the Researcher role, which is correct. The cause can also be a role
assignment that is not yet in effect.

This also makes tests more difficult. Each role sees a different page, so you must
test a change to a controlled function with each role. Today you change the app
role assignment in Entra ID, open the UI again, and then look at the buttons to
decide if the new role is in effect.

How is this addressed

The user menu now shows the roles that the user has.

  • The menu button shows a summary line below the name. The user does not have to
    open the menu to see it.
  • The menu lists TRE roles. On a workspace route it also lists
    Workspace roles.
  • A scope with no roles shows None assigned. The UI does not show an empty
    area. This condition is the most difficult one to find today.
  • The UI shows a display name for each role. TREAdmin becomes
    TRE Administrator. An unknown value keeps its raw text, so a new app role is
    still shown.

The button has room for one line. Thus the summary gives the name of one role and
counts the others: Workspace Owner +2 more. A token lists the roles in no
guaranteed order, so the roles are sorted first and the summary names the most
privileged one. The same order applies to the menu.

Inside a workspace the summary gives the workspace roles. A TRE Admin has no
workspace role there, so the summary falls back to the core roles instead of
No roles assigned.

TopNav takes the workspace roles as a property, because it is outside the
WorkspaceContext provider and cannot read them. The state is already in
App, and WorkspaceProvider clears it when it unmounts.

The menu reads the same token claims that SecuredByRole uses. It does not read
Entra ID. Thus the menu and the available functions always agree. A difference
would show that the browser has an old token, which is useful data.

Screenshots

One role, and more than one role:

Role summary on the menu button

A TRE Admin in a workspace with no workspace role, and a user with no roles:

Empty role states

The menu open, for a user with all three workspace roles:

User menu open

The screenshots come from a preview harness that renders the component with a
stub in place of MSAL. The harness is not part of this change.

Checks

  • npx vitest run: 27 files and 250 tests pass. UserMenu.tsx and
    roleNames.ts are at 100% for statements, branches, functions and lines.
  • npx eslint . is clean. npx prettier --check src is clean.
    npm run build passes.
  • ui/app/package.json moves to 0.8.32. There is a CHANGELOG entry, and the
    AuthN + AuthZ section of docs/tre-developers/ui.md is updated.

Open points

  • The role entries are menu items with no action. A read-only section in a
    contextual menu is not a usual use of the control. I can move the roles to a
    callout or a panel if that is better.
  • The persona is now size40, because Fluent does not show the secondary text
    below that size. The bar is 50px high, so the bar itself does not change.
  • The workspace roles are empty for a moment while a workspace loads. The menu
    shows None assigned until the roles arrive.
  • The role items carry a Contact icon. No icon shows at present, because the
    app does not call initializeIcons(). The SignOut icon on the Logout item
    has the same condition. This is not new, and it is not part of this change.

The UI already holds the signed-in user's roles in AppRolesContext and
WorkspaceContext, but only uses them to decide which elements to render.
When SecuredByRole removes an element, the user cannot tell whether that
is expected for their role or whether a role assignment has not taken
effect yet.

Show the roles in the user menu instead:

- The button summarises the roles for the scope being viewed, so the
  indicator is visible without opening the menu.
- The menu lists TRE roles, and workspace roles on a workspace route.
- An empty scope reads "None assigned" rather than rendering nothing,
  which is the state that is hardest to diagnose today.
- Role values are mapped to display names, falling back to the raw value
  so a newly added app role is still shown.

TopNav takes the workspace roles as a prop because it sits outside the
WorkspaceContext provider. The roles come from the same token claims that
SecuredByRole gates on, so the menu cannot disagree with what the UI
allows.
@github-actions

Copy link
Copy Markdown

Unit Test Results

250 tests   250 ✅  16s ⏱️
 27 suites    0 💤
  1 files      0 ❌

Results for commit f630a1c.

@marrobi

Marcus Robinson (marrobi) commented Aug 20, 2026

Copy link
Copy Markdown
Member

Jay W (@JayDoubleu) thanks. I think below the name looks cluttered. Thoughts on these options:

image

I quite like number 2.

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.

The UI does not show the roles that the user has

2 participants