Truncate access review roles with badge list

Long role strings in the access review table broke row layout when
drivers joined many roles into one comma-separated value. Expose
roles as a string array in GraphQL by splitting the stored role at
the API layer, and render the first three roles as badges with a
"+X more" popover for the rest.

Closes ENG-459.

Signed-off-by: Ludovic Vielle <ludovic@probo.com>
This commit is contained in:
Ludovic Vielle
2026-06-12 18:23:04 +02:00
parent bf20ca1a90
commit 8094e7cfd0
80 changed files with 768 additions and 378 deletions

View File

@@ -164,16 +164,16 @@ func (d *Microsoft365Driver) ListAccounts(ctx context.Context) ([]AccountRecord,
}
}
role := pickHighestRole(userRoles)
if role == "" {
role = "User"
roles := userRoles
if len(roles) == 0 {
roles = []string{"User"}
}
active := u.AccountEnabled
rec := AccountRecord{
Email: email,
FullName: u.DisplayName,
Role: role,
Roles: roles,
JobTitle: u.JobTitle,
Active: &active,
IsAdmin: isAdmin,
@@ -195,39 +195,6 @@ func (d *Microsoft365Driver) ListAccounts(ctx context.Context) ([]AccountRecord,
return records, nil
}
// pickHighestRole returns the most privileged admin role from the list,
// falling back to the first non-admin role when no admin role is present.
// Privilege order is hard-coded to Microsoft's well-known directory roles.
func pickHighestRole(roles []string) string {
priority := []string{
"Global Administrator",
"Company Administrator",
"Privileged Role Administrator",
"Privileged Authentication Administrator",
"Security Administrator",
"Application Administrator",
"Cloud Application Administrator",
"User Administrator",
"Conditional Access Administrator",
"Compliance Administrator",
"Authentication Administrator",
}
for _, p := range priority {
for _, r := range roles {
if r == p {
return r
}
}
}
if len(roles) > 0 {
return roles[0]
}
return ""
}
func (d *Microsoft365Driver) listUsers(ctx context.Context) ([]microsoft365User, error) {
pageURL, err := buildMicrosoft365UsersURL()
if err != nil {