diff --git a/site/src/components/UserDropdown/UserDropdown.stories.tsx b/site/src/components/UserDropdown/UserDropdown.stories.tsx index 48fb3650478dd..14d89ee5d37e8 100644 --- a/site/src/components/UserDropdown/UserDropdown.stories.tsx +++ b/site/src/components/UserDropdown/UserDropdown.stories.tsx @@ -1,6 +1,7 @@ import Box from "@material-ui/core/Box" import { Story } from "@storybook/react" import React from "react" +import { MockUser } from "../../testHelpers/entities" import { UserDropdown, UserDropdownProps } from "./UsersDropdown" export default { @@ -17,9 +18,9 @@ const Template: Story = (args: UserDropdownProps) => ( ) -export const Example = Template.bind({}) -Example.args = { - user: { id: "1", username: "CathyCoder", email: "cathy@coder.com", created_at: "dawn" }, +export const ExampleNoRoles = Template.bind({}) +ExampleNoRoles.args = { + user: MockUser, onSignOut: () => { return Promise.resolve() }, diff --git a/site/src/components/UserDropdown/UserDropdown.test.tsx b/site/src/components/UserDropdown/UserDropdown.test.tsx index 3a71246eaa9e4..6e9422eded0a7 100644 --- a/site/src/components/UserDropdown/UserDropdown.test.tsx +++ b/site/src/components/UserDropdown/UserDropdown.test.tsx @@ -1,6 +1,6 @@ import { screen } from "@testing-library/react" import React from "react" -import { MockUser } from "../../testHelpers/entities" +import { MockAdminRole, MockMemberRole, MockUser } from "../../testHelpers/entities" import { render } from "../../testHelpers/renderHelpers" import { Language, UserDropdown, UserDropdownProps } from "./UsersDropdown" @@ -33,6 +33,36 @@ describe("UserDropdown", () => { }) describe("when the menu is open", () => { + it("displays the user's roles", async () => { + 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 () => { + process.env.CODER_VERSION = "v0.5.4" + await renderAndClick() + + const link = screen.getByText(Language.docsLabel).closest("a") + if (!link) { + throw new Error("Anchor tag not found for the documentation menu item") + } + + expect(link.getAttribute("href")).toBe(`https://github.com/coder/coder/tree/${process.env.CODER_VERSION}/docs`) + }) + + it("has the correct link for the account item", async () => { + await renderAndClick() + + const link = screen.getByText(Language.accountLabel).closest("a") + if (!link) { + throw new Error("Anchor tag not found for the account menu item") + } + + expect(link.getAttribute("href")).toBe("/settings/account") + }) + describe("and sign out is clicked", () => { it("calls the onSignOut function", async () => { const onSignOut = jest.fn() @@ -42,27 +72,4 @@ describe("UserDropdown", () => { }) }) }) - - it("has the correct link for the documentation item", async () => { - process.env.CODER_VERSION = "v0.5.4" - await renderAndClick() - - const link = screen.getByText(Language.docsLabel).closest("a") - if (!link) { - throw new Error("Anchor tag not found for the documentation menu item") - } - - expect(link.getAttribute("href")).toBe(`https://github.com/coder/coder/tree/${process.env.CODER_VERSION}/docs`) - }) - - it("has the correct link for the account item", async () => { - await renderAndClick() - - const link = screen.getByText(Language.accountLabel).closest("a") - if (!link) { - throw new Error("Anchor tag not found for the account menu item") - } - - expect(link.getAttribute("href")).toBe("/settings/account") - }) }) diff --git a/site/src/components/UserProfileCard/UserProfileCard.stories.tsx b/site/src/components/UserProfileCard/UserProfileCard.stories.tsx new file mode 100644 index 0000000000000..92754f0709fcf --- /dev/null +++ b/site/src/components/UserProfileCard/UserProfileCard.stories.tsx @@ -0,0 +1,42 @@ +import { Story } from "@storybook/react" +import React from "react" +import { MockUser } from "../../testHelpers/entities" +import { UserProfileCard, UserProfileCardProps } from "./UserProfileCard" + +export default { + title: "components/UserDropdown", + component: UserProfileCard, + argTypes: { + onSignOut: { action: "Sign Out" }, + }, +} + +const Template: Story = (args: UserProfileCardProps) => + +export const ExampleNoRoles = Template.bind({}) +ExampleNoRoles.args = { + user: { + ...MockUser, + roles: [], + }, +} + +export const ExampleOneRole = Template.bind({}) +ExampleOneRole.args = { + user: { + ...MockUser, + roles: [{ name: "member", display_name: "Member" }], + }, +} + +export const ExampleThreeRoles = Template.bind({}) +ExampleThreeRoles.args = { + user: { + ...MockUser, + roles: [ + { name: "admin", display_name: "Admin" }, + { name: "member", display_name: "Member" }, + { name: "auditor", display_name: "Auditor" }, + ], + }, +} diff --git a/site/src/components/UserProfileCard/UserProfileCard.tsx b/site/src/components/UserProfileCard/UserProfileCard.tsx index dc63b08ea2ef0..020461dfcf573 100644 --- a/site/src/components/UserProfileCard/UserProfileCard.tsx +++ b/site/src/components/UserProfileCard/UserProfileCard.tsx @@ -1,10 +1,12 @@ +import Chip from "@material-ui/core/Chip" import { makeStyles } from "@material-ui/core/styles" import Typography from "@material-ui/core/Typography" import React from "react" import * as TypesGen from "../../api/typesGenerated" +import { Role } from "../../api/typesGenerated" import { UserAvatar } from "../UserAvatar/UserAvatar" -interface UserProfileCardProps { +export interface UserProfileCardProps { user: TypesGen.User } @@ -18,6 +20,13 @@ export const UserProfileCard: React.FC = ({ user }) => { {user.username} {user.email} +
    + {user.roles.map((role: Role) => ( +
  • + +
  • + ))} +
) } @@ -52,6 +61,19 @@ const useStyles = makeStyles((theme) => ({ fontSize: 14, letterSpacing: 0.2, color: theme.palette.text.secondary, - marginBottom: theme.spacing(1.5), + }, + chipContainer: { + display: "flex", + justifyContent: "center", + flexWrap: "wrap", + listStyle: "none", + margin: "0", + padding: `${theme.spacing(1.5)}px ${theme.spacing(2.75)}px`, + }, + chipStyles: { + margin: theme.spacing(0.5), + }, + chipRoot: { + backgroundColor: "#7057FF", }, }))