Skip to content

FEAT [GUI] Display signed-in user info in top bar and populate operator label with username#1636

Open
behnam-o wants to merge 17 commits intomicrosoft:mainfrom
behnam-o:dev/gui-username
Open

FEAT [GUI] Display signed-in user info in top bar and populate operator label with username#1636
behnam-o wants to merge 17 commits intomicrosoft:mainfrom
behnam-o:dev/gui-username

Conversation

@behnam-o
Copy link
Copy Markdown
Contributor

@behnam-o behnam-o commented Apr 21, 2026

Adds a component to display the currently-signed-in user on the top right of the GUI, and sets the operator label value as the username on load/login

This is what it looks like:
image

If running locally, the top bar component is not added, and the label value is not updated. i.e.
image

Note:
Testing in local is a little tricky in our current setup, because we have some logic in place to bypass auth altogether if a local env is detected. We need to fix that, but this is the workaround I used to force auth on local env, to test this change:

  1. create an app registration with http://localhost as its redirect URI
  2. set ENTRA_TENANT_ID and ENTRA_CLIENT_ID evn variables (from above) before running python dev.py start (which starts the backend and front end)
  3. in msalconfig.ts, return exactly ["openid"] instead of ["api://***"] (this basically means 'https://graph.microsoft.com/openid')
  4. for some reason, the LoginRedirect component is weird when running locally, so I had to comment it out in AuthProvider.ts and instead create a manual login button like this:
<UnauthenticatedTemplate>
 {/* <LoginRedirect /> */}
 <button onClick={() => msalInstance.loginRedirect(buildLoginRequest(authConfig.clientId))}>Log In</button>
</UnauthenticatedTemplate>

@behnam-o behnam-o marked this pull request as ready for review April 21, 2026 21:40
@romanlutz
Copy link
Copy Markdown
Contributor

romanlutz commented Apr 21, 2026

Needs tests for when it can't resolve the user. For example, if you're running it locally and aren't logged in.

Also, this should auto-populate the operator (with alias presumably?) so that people don't have to keep re-setting that.

@behnam-o behnam-o changed the title FEAT [GUI] Display signed-in user info in top bar FEAT [GUI] Display signed-in user info in top bar and populate operator label with username Apr 21, 2026
</TestWrapper>
)

fireEvent.click(screen.getByRole('button', { name: /log in/i }))
Copy link
Copy Markdown
Contributor

@jbolor21 jbolor21 Apr 22, 2026

Choose a reason for hiding this comment

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

this should prob be userEvent instead of fireEvent
you can do something like

const user = userEvent.setup()
    // ...render...
    await user.click(screen.getByRole('button', { name: /log in/i }))

For the popover test (Sign Out), you do two sequential clicks — 1) open the popover, 2) click "Sign Out" inside it. With fireEvent you won't care about whether it has actually rendered or whether the element is visible/interactable vs w the userEvent.click you simulate the full browser interaction chain

fireEvent.click(screen.getByRole('button', { name: /alice smith/i }))

fireEvent.click(screen.getByRole('button', { name: /sign out/i }))

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.

similarly here think it should be something like:

const user = userEvent.setup()
// ...render...
await user.click(screen.getByRole('button', { name: /alice smith/i }))
await user.click(screen.getByRole('button', { name: /sign out/i }))
expect(mockLogoutRedirect).toHaveBeenCalled()

})

import { render, screen, fireEvent } from '@testing-library/react'
import { FluentProvider, webLightTheme } from '@fluentui/react-components'
import { UserAccountButton } from './UserAccountButton'

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.

add import userEvent from '@testing-library/user-event'

expect.any(String)
)
})

Copy link
Copy Markdown
Contributor

@jbolor21 jbolor21 Apr 22, 2026

Choose a reason for hiding this comment

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

are these new lines needed? i don't think they are but correct me if I'm wrong :)

)
}

const displayName = account.name ?? account.username ?? 'User'
Copy link
Copy Markdown
Contributor

@jbolor21 jbolor21 Apr 22, 2026

Choose a reason for hiding this comment

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

nit: maybe change to || instead of ?? to catch the empty string vs the ?? will let it pass through i think!

<Button
appearance="subtle"
icon={<PersonRegular />}
onClick={() => instance.loginRedirect(buildLoginRequest(config.clientId))}
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.

nit: add checking for failure here?

onClick={() => {
instance.loginRedirect(buildLoginRequest(config.clientId)).catch((err) => {
console.error('Login redirect failed:', err)
})
}}

)}
<Button
appearance="secondary"
onClick={() => instance.logoutRedirect()}
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.

nit: and add similar error catch here too?

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.

3 participants