Skip to content

Commit

Permalink
fix: Display member role when user has no role (#1965)
Browse files Browse the repository at this point in the history
  • Loading branch information
BrunoQuaresma committed Jun 2, 2022
1 parent dcf03d8 commit 3fd4dcd
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 54 deletions.
2 changes: 1 addition & 1 deletion site/src/components/RoleSelect/RoleSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export const RoleSelect: FC<RoleSelectProps> = ({ roles, selectedRoles, loading,

return (
<MenuItem key={r.name} value={r.name} disabled={loading}>
<Checkbox color="primary" checked={isChecked} /> {r.display_name}
<Checkbox size="small" color="primary" checked={isChecked} /> {r.display_name}
</MenuItem>
)
})}
Expand Down
3 changes: 1 addition & 2 deletions site/src/components/UserDropdown/UserDropdown.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { screen } from "@testing-library/react"
import { MockAdminRole, MockMemberRole, MockUser } from "../../testHelpers/entities"
import { MockAdminRole, MockUser } from "../../testHelpers/entities"
import { render } from "../../testHelpers/renderHelpers"
import { Language, UserDropdown, UserDropdownProps } from "./UsersDropdown"

Expand Down Expand Up @@ -36,7 +36,6 @@ describe("UserDropdown", () => {
await renderAndClick()

expect(screen.getByText(MockAdminRole.display_name)).toBeDefined()
expect(screen.getByText(MockMemberRole.display_name)).toBeDefined()
})

it("has the correct link for the documentation item", async () => {
Expand Down
127 changes: 80 additions & 47 deletions site/src/components/UsersTable/UsersTable.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import Box from "@material-ui/core/Box"
import { makeStyles } from "@material-ui/core/styles"
import Table from "@material-ui/core/Table"
import TableBody from "@material-ui/core/TableBody"
import TableCell from "@material-ui/core/TableCell"
import TableHead from "@material-ui/core/TableHead"
import TableRow from "@material-ui/core/TableRow"
import { FC } from "react"
import * as TypesGen from "../../api/typesGenerated"
import { combineClasses } from "../../util/combineClasses"
import { AvatarData } from "../AvatarData/AvatarData"
import { EmptyState } from "../EmptyState/EmptyState"
import { RoleSelect } from "../RoleSelect/RoleSelect"
Expand Down Expand Up @@ -45,6 +47,8 @@ export const UsersTable: FC<UsersTableProps> = ({
canEditUsers,
isLoading,
}) => {
const styles = useStyles()

return (
<Table>
<TableHead>
Expand All @@ -60,55 +64,75 @@ export const UsersTable: FC<UsersTableProps> = ({
{isLoading && <TableLoader />}
{!isLoading &&
users &&
users.map((u) => (
<TableRow key={u.id}>
<TableCell>
<AvatarData title={u.username} subtitle={u.email} />
</TableCell>
<TableCell>{u.status}</TableCell>
<TableCell>
{canEditUsers ? (
<RoleSelect
roles={roles ?? []}
selectedRoles={u.roles}
loading={isUpdatingUserRoles}
onChange={(roles) => onUpdateUserRoles(u, roles)}
/>
) : (
<>{u.roles.map((r) => r.display_name).join(", ")}</>
)}
</TableCell>
{canEditUsers && (
users.map((user) => {
// When the user has no role we want to show they are a Member
const fallbackRole: TypesGen.Role = {
name: "member",
display_name: "Member",
}
const userRoles = user.roles.length === 0 ? [fallbackRole] : user.roles

return (
<TableRow key={user.id}>
<TableCell>
<AvatarData title={user.username} subtitle={user.email} />
</TableCell>
<TableCell
className={combineClasses([
styles.status,
user.status === "suspended" ? styles.suspended : undefined,
])}
>
{user.status}
</TableCell>
<TableCell>
<TableRowMenu
data={u}
menuItems={
// Return either suspend or activate depending on status
(u.status === "active"
? [
{
label: Language.suspendMenuItem,
onClick: onSuspendUser,
},
]
: [
// TODO: Uncomment this and add activate user functionality.
// {
// label: Language.activateMenuItem,
// // eslint-disable-next-line @typescript-eslint/no-empty-function
// onClick: function () {},
// },
]
).concat({
label: Language.resetPasswordMenuItem,
onClick: onResetUserPassword,
})
}
/>
{canEditUsers ? (
<RoleSelect
roles={roles ?? []}
selectedRoles={userRoles}
loading={isUpdatingUserRoles}
onChange={(roles) => {
// Remove the fallback role because it is only for the UI
roles = roles.filter((role) => role !== fallbackRole.name)
onUpdateUserRoles(user, roles)
}}
/>
) : (
<>{userRoles.map((role) => role.display_name).join(", ")}</>
)}
</TableCell>
)}
</TableRow>
))}
{canEditUsers && (
<TableCell>
<TableRowMenu
data={user}
menuItems={
// Return either suspend or activate depending on status
(user.status === "active"
? [
{
label: Language.suspendMenuItem,
onClick: onSuspendUser,
},
]
: [
// TODO: Uncomment this and add activate user functionality.
// {
// label: Language.activateMenuItem,
// // eslint-disable-next-line @typescript-eslint/no-empty-function
// onClick: function () {},
// },
]
).concat({
label: Language.resetPasswordMenuItem,
onClick: onResetUserPassword,
})
}
/>
</TableCell>
)}
</TableRow>
)
})}

{users && users.length === 0 && (
<TableRow>
Expand All @@ -123,3 +147,12 @@ export const UsersTable: FC<UsersTableProps> = ({
</Table>
)
}

const useStyles = makeStyles((theme) => ({
status: {
textTransform: "capitalize",
},
suspended: {
color: theme.palette.text.secondary,
},
}))
2 changes: 1 addition & 1 deletion site/src/pages/UsersPage/UsersPage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ describe("Users Page", () => {
}, MockAuditorRole)

// Check if the select text was updated with the Auditor role
await waitFor(() => expect(rolesMenuTrigger).toHaveTextContent("Admin, Member, Auditor"))
await waitFor(() => expect(rolesMenuTrigger).toHaveTextContent("Admin, Auditor"))

// Check if the API was called correctly
const currentRoles = MockUser.roles.map((r) => r.name)
Expand Down
6 changes: 3 additions & 3 deletions site/src/testHelpers/entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const MockAuditorRole: TypesGen.Role = {
display_name: "Auditor",
}

export const MockSiteRoles = [MockAdminRole, MockAuditorRole, MockMemberRole]
export const MockSiteRoles = [MockAdminRole, MockAuditorRole]

export const MockUser: TypesGen.User = {
id: "test-user",
Expand All @@ -38,7 +38,7 @@ export const MockUser: TypesGen.User = {
created_at: "",
status: "active",
organization_ids: ["fc0774ce-cc9e-48d4-80ae-88f7a4d4a8b0"],
roles: [MockAdminRole, MockMemberRole],
roles: [MockAdminRole],
}

export const MockUser2: TypesGen.User = {
Expand All @@ -48,7 +48,7 @@ export const MockUser2: TypesGen.User = {
created_at: "",
status: "active",
organization_ids: ["fc0774ce-cc9e-48d4-80ae-88f7a4d4a8b0"],
roles: [MockMemberRole],
roles: [],
}

export const MockOrganization: TypesGen.Organization = {
Expand Down

0 comments on commit 3fd4dcd

Please sign in to comment.