From d2ab1b95bbf03405ee2100962c8ed6a937b1e2ad Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Wed, 4 Jan 2023 17:28:23 +0000 Subject: [PATCH 01/10] Update FE with the new roles popover --- .../EditRolesButton/EditRolesButton.tsx | 202 ++++++++++++++++++ site/src/components/Icons/EditSquare.tsx | 7 + site/src/components/UsersTable/UsersTable.tsx | 9 +- .../components/UsersTable/UsersTableBody.tsx | 69 +++--- site/src/i18n/en/usersPage.json | 3 +- 5 files changed, 253 insertions(+), 37 deletions(-) create mode 100644 site/src/components/EditRolesButton/EditRolesButton.tsx create mode 100644 site/src/components/Icons/EditSquare.tsx diff --git a/site/src/components/EditRolesButton/EditRolesButton.tsx b/site/src/components/EditRolesButton/EditRolesButton.tsx new file mode 100644 index 0000000000000..c9abdc63952bf --- /dev/null +++ b/site/src/components/EditRolesButton/EditRolesButton.tsx @@ -0,0 +1,202 @@ +import IconButton from "@material-ui/core/IconButton" +import { EditSquare } from "components/Icons/EditSquare" +import { useRef, useState, FC } from "react" +import { makeStyles } from "@material-ui/core/styles" +import { useTranslation } from "react-i18next" +import Popover from "@material-ui/core/Popover" +import { Stack } from "components/Stack/Stack" +import Checkbox from "@material-ui/core/Checkbox" +import UserIcon from "@material-ui/icons/PersonOutline" +import { AssignableRoles, Role } from "api/typesGenerated" + +const Option: React.FC<{ + value: string + name: string + description: string + isChecked: boolean + onChange: (roleName: string) => void +}> = ({ value, name, description, isChecked, onChange }) => { + const styles = useStyles() + + return ( + + ) +} + +export const EditRolesButton: FC<{ + isLoading: boolean + roles: AssignableRoles[] + selectedRoles: Role[] + onChange: (roles: Role["name"][]) => void +}> = ({ roles, selectedRoles, onChange, isLoading }) => { + const styles = useStyles() + const { t } = useTranslation("usersPage") + const anchorRef = useRef(null) + const [isOpen, setIsOpen] = useState(false) + const id = isOpen ? "edit-roles-popover" : undefined + const selectedRoleNames = selectedRoles.map((role) => role.name) + + const handleChange = (roleName: string) => { + if (selectedRoleNames.includes(roleName)) { + onChange(selectedRoleNames.filter((role) => role !== roleName)) + return + } + + onChange([...selectedRoleNames, roleName]) + } + + return ( + <> + setIsOpen(true)} + > + + + + setIsOpen(false)} + anchorOrigin={{ + vertical: "bottom", + horizontal: "right", + }} + transformOrigin={{ + vertical: "top", + horizontal: "right", + }} + classes={{ paper: styles.popoverPaper }} + > +
+ + +
+
+ + + + Member + + Everybody is a member. This is a shared and default role for all + the users. + + + +
+
+ + ) +} + +const useStyles = makeStyles((theme) => ({ + editButton: { + color: theme.palette.text.secondary, + + "& .MuiSvgIcon-root": { + width: theme.spacing(2), + height: theme.spacing(2), + position: "relative", + top: -2, // Align the pencil square + }, + + "&:hover": { + color: theme.palette.text.primary, + backgroundColor: "transparent", + }, + }, + popoverPaper: { + width: theme.spacing(45), + marginTop: theme.spacing(1), + background: theme.palette.background.paperLight, + }, + fieldset: { + border: 0, + margin: 0, + padding: 0, + + "&:disabled": { + opacity: 0.5, + }, + }, + options: { + padding: theme.spacing(3), + }, + option: { + cursor: "pointer", + }, + checkbox: { + padding: 0, + position: "relative", + top: 1, // Alignment + + "& svg": { + width: theme.spacing(2.5), + height: theme.spacing(2.5), + }, + }, + optionDescription: { + fontSize: 12, + color: theme.palette.text.secondary, + }, + footer: { + padding: theme.spacing(3), + backgroundColor: theme.palette.background.paper, + borderTop: `1px solid ${theme.palette.divider}`, + }, + userIcon: { + width: theme.spacing(2.5), // Same as the checkbox + height: theme.spacing(2.5), + color: theme.palette.primary.main, + }, +})) diff --git a/site/src/components/Icons/EditSquare.tsx b/site/src/components/Icons/EditSquare.tsx new file mode 100644 index 0000000000000..f727ba3b2e145 --- /dev/null +++ b/site/src/components/Icons/EditSquare.tsx @@ -0,0 +1,7 @@ +import SvgIcon, { SvgIconProps } from "@material-ui/core/SvgIcon" + +export const EditSquare = (props: SvgIconProps): JSX.Element => ( + + + +) diff --git a/site/src/components/UsersTable/UsersTable.tsx b/site/src/components/UsersTable/UsersTable.tsx index d5210f803a8a4..869d548a41c29 100644 --- a/site/src/components/UsersTable/UsersTable.tsx +++ b/site/src/components/UsersTable/UsersTable.tsx @@ -54,15 +54,16 @@ export const UsersTable: FC> = ({ - {Language.usernameLabel} - {Language.statusLabel} - {Language.lastSeenLabel} - + {Language.usernameLabel} + {Language.rolesLabel} + {Language.statusLabel} + {Language.lastSeenLabel} + {/* 1% is a trick to make the table cell width fit the content */} {canEditUsers && } diff --git a/site/src/components/UsersTable/UsersTableBody.tsx b/site/src/components/UsersTable/UsersTableBody.tsx index 5a7c0dc3144c4..6a8ebbcd71b98 100644 --- a/site/src/components/UsersTable/UsersTableBody.tsx +++ b/site/src/components/UsersTable/UsersTableBody.tsx @@ -11,10 +11,14 @@ 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" import { TableLoader } from "../TableLoader/TableLoader" import { TableRowMenu } from "../TableRowMenu/TableRowMenu" +import { EditRolesButton } from "components/EditRolesButton/EditRolesButton" +import { Stack } from "components/Stack/Stack" +const isAdminRole = (role: TypesGen.Role): boolean => { + return role.name === "owner" || role.name.includes("admin") +} interface UsersTableBodyProps { users?: TypesGen.User[] roles?: TypesGen.AssignableRoles[] @@ -109,6 +113,34 @@ export const UsersTableBody: FC< } /> + + + {canEditUsers && ( + { + // Remove the fallback role because it is only for the UI + roles = roles.filter( + (role) => role !== fallbackRole.name, + ) + onUpdateUserRoles(user, roles) + }} + /> + )} + {userRoles.map((role) => ( + + ))} + + - - {canEditUsers ? ( - { - // Remove the fallback role because it is only for the UI - roles = roles.filter( - (role) => role !== fallbackRole.name, - ) - onUpdateUserRoles(user, roles) - }} - /> - ) : ( -
- {userRoles.map((role) => ( - - ))} -
- )} -
{canEditUsers && ( ({ height: theme.spacing(4.5), borderRadius: "100%", }, - roles: { - display: "flex", - gap: theme.spacing(1), - flexWrap: "wrap", - }, rolePill: { backgroundColor: theme.palette.background.paperLight, borderColor: theme.palette.divider, }, + rolePillAdmin: { + backgroundColor: theme.palette.info.dark, + borderColor: theme.palette.info.light, + }, })) diff --git a/site/src/i18n/en/usersPage.json b/site/src/i18n/en/usersPage.json index e1f84b93df7f5..9219779a8139e 100644 --- a/site/src/i18n/en/usersPage.json +++ b/site/src/i18n/en/usersPage.json @@ -5,5 +5,6 @@ "deleteMenuItem": "Delete", "listWorkspacesMenuItem": "View workspaces", "activateMenuItem": "Activate", - "resetPasswordMenuItem": "Reset password" + "resetPasswordMenuItem": "Reset password", + "editUserRolesTooltip": "Edit user roles" } From f5b1b23f12cc01c37c073fc8d4f12bbd58290374 Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Wed, 4 Jan 2023 18:02:36 +0000 Subject: [PATCH 02/10] Predicatable sorting --- .../EditRolesButton/EditRolesButton.tsx | 47 ++++++------------- .../components/UsersTable/UsersTableBody.tsx | 13 ++++- site/src/i18n/en/usersPage.json | 10 +++- 3 files changed, 34 insertions(+), 36 deletions(-) diff --git a/site/src/components/EditRolesButton/EditRolesButton.tsx b/site/src/components/EditRolesButton/EditRolesButton.tsx index c9abdc63952bf..c0bdc0f8769bf 100644 --- a/site/src/components/EditRolesButton/EditRolesButton.tsx +++ b/site/src/components/EditRolesButton/EditRolesButton.tsx @@ -7,7 +7,7 @@ import Popover from "@material-ui/core/Popover" import { Stack } from "components/Stack/Stack" import Checkbox from "@material-ui/core/Checkbox" import UserIcon from "@material-ui/icons/PersonOutline" -import { AssignableRoles, Role } from "api/typesGenerated" +import { Role } from "api/typesGenerated" const Option: React.FC<{ value: string @@ -43,7 +43,7 @@ const Option: React.FC<{ export const EditRolesButton: FC<{ isLoading: boolean - roles: AssignableRoles[] + roles: Role[] selectedRoles: Role[] onChange: (roles: Role["name"][]) => void }> = ({ roles, selectedRoles, onChange, isLoading }) => { @@ -92,44 +92,25 @@ export const EditRolesButton: FC<{ >
-
- Member + {t("member")} - Everybody is a member. This is a shared and default role for all - the users. + {t("roleDescription.member")} diff --git a/site/src/components/UsersTable/UsersTableBody.tsx b/site/src/components/UsersTable/UsersTableBody.tsx index 6a8ebbcd71b98..bfcac14dfb93d 100644 --- a/site/src/components/UsersTable/UsersTableBody.tsx +++ b/site/src/components/UsersTable/UsersTableBody.tsx @@ -19,6 +19,15 @@ import { Stack } from "components/Stack/Stack" const isAdminRole = (role: TypesGen.Role): boolean => { return role.name === "owner" || role.name.includes("admin") } + +const roleOrder = ["owner", "user-admin", "template-admin", "auditor"] + +const sortRoles = (roles: TypesGen.Role[]) => { + return roles.slice(0).sort((a, b) => { + return roleOrder.indexOf(a.name) - roleOrder.indexOf(b.name) + }) +} + interface UsersTableBodyProps { users?: TypesGen.User[] roles?: TypesGen.AssignableRoles[] @@ -93,7 +102,7 @@ export const UsersTableBody: FC< display_name: "Member", } const userRoles = - user.roles.length === 0 ? [fallbackRole] : user.roles + user.roles.length === 0 ? [fallbackRole] : sortRoles(user.roles) return ( @@ -117,7 +126,7 @@ export const UsersTableBody: FC< {canEditUsers && ( { diff --git a/site/src/i18n/en/usersPage.json b/site/src/i18n/en/usersPage.json index 9219779a8139e..7fe06866309a8 100644 --- a/site/src/i18n/en/usersPage.json +++ b/site/src/i18n/en/usersPage.json @@ -6,5 +6,13 @@ "listWorkspacesMenuItem": "View workspaces", "activateMenuItem": "Activate", "resetPasswordMenuItem": "Reset password", - "editUserRolesTooltip": "Edit user roles" + "editUserRolesTooltip": "Edit user roles", + "roleDescription": { + "owner": "Admin can manage all the coder resources including users and their permissions", + "user-admin": "Admin can manage all the coder resources including users and their permissions", + "template-admin": "Admin can manage all the coder resources including users and their permissions", + "auditor": "Admin can manage all the coder resources including users and their permissions", + "member": "Admin can manage all the coder resources including users and their permissions" + }, + "member": "Member" } From 513de242639aac30b1598ef3c257cd176a150b29 Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Wed, 4 Jan 2023 18:05:54 +0000 Subject: [PATCH 03/10] Add predicatble sorting --- .../EditRolesButton/EditRolesButton.tsx | 4 +- .../RoleSelect/RoleSelect.stories.tsx | 45 ----------- .../components/RoleSelect/RoleSelect.test.tsx | 50 ------------ site/src/components/RoleSelect/RoleSelect.tsx | 79 ------------------- 4 files changed, 2 insertions(+), 176 deletions(-) delete mode 100644 site/src/components/RoleSelect/RoleSelect.stories.tsx delete mode 100644 site/src/components/RoleSelect/RoleSelect.test.tsx delete mode 100644 site/src/components/RoleSelect/RoleSelect.tsx diff --git a/site/src/components/EditRolesButton/EditRolesButton.tsx b/site/src/components/EditRolesButton/EditRolesButton.tsx index c0bdc0f8769bf..e8facc0f8968e 100644 --- a/site/src/components/EditRolesButton/EditRolesButton.tsx +++ b/site/src/components/EditRolesButton/EditRolesButton.tsx @@ -82,11 +82,11 @@ export const EditRolesButton: FC<{ onClose={() => setIsOpen(false)} anchorOrigin={{ vertical: "bottom", - horizontal: "right", + horizontal: "left", }} transformOrigin={{ vertical: "top", - horizontal: "right", + horizontal: "left", }} classes={{ paper: styles.popoverPaper }} > diff --git a/site/src/components/RoleSelect/RoleSelect.stories.tsx b/site/src/components/RoleSelect/RoleSelect.stories.tsx deleted file mode 100644 index 7cb6717873f8d..0000000000000 --- a/site/src/components/RoleSelect/RoleSelect.stories.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { ComponentMeta, Story } from "@storybook/react" -import { - assignableRole, - MockAuditorRole, - MockMemberRole, - MockOwnerRole, - MockTemplateAdminRole, - MockUserAdminRole, -} from "../../testHelpers/renderHelpers" -import { RoleSelect, RoleSelectProps } from "./RoleSelect" - -export default { - title: "components/RoleSelect", - component: RoleSelect, -} as ComponentMeta - -const Template: Story = (args) => - -// Include 4 roles: -// - owner (disabled, not checked) -// - template admin (disabled, checked) -// - auditor (enabled, not checked) -// - user admin (enabled, checked) -export const Close = Template.bind({}) -Close.args = { - roles: [ - assignableRole(MockOwnerRole, false), - assignableRole(MockTemplateAdminRole, false), - assignableRole(MockAuditorRole, true), - assignableRole(MockUserAdminRole, true), - ], - selectedRoles: [MockUserAdminRole, MockTemplateAdminRole, MockMemberRole], -} - -export const Open = Template.bind({}) -Open.args = { - open: true, - roles: [ - assignableRole(MockOwnerRole, false), - assignableRole(MockTemplateAdminRole, false), - assignableRole(MockAuditorRole, true), - assignableRole(MockUserAdminRole, true), - ], - selectedRoles: [MockUserAdminRole, MockTemplateAdminRole, MockMemberRole], -} diff --git a/site/src/components/RoleSelect/RoleSelect.test.tsx b/site/src/components/RoleSelect/RoleSelect.test.tsx deleted file mode 100644 index 7bd05b62c6dfe..0000000000000 --- a/site/src/components/RoleSelect/RoleSelect.test.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { screen } from "@testing-library/react" -import { - assignableRole, - MockAuditorRole, - MockMemberRole, - MockOwnerRole, - MockTemplateAdminRole, - MockUserAdminRole, - render, -} from "testHelpers/renderHelpers" -import { RoleSelect } from "./RoleSelect" - -describe("UserRoleSelect", () => { - it("renders content", async () => { - // When - render( - , - ) - - // Then - const owner = await screen.findByText(MockOwnerRole.display_name) - const templateAdmin = await screen.findByText( - MockTemplateAdminRole.display_name, - ) - const auditor = await screen.findByText(MockAuditorRole.display_name) - const userAdmin = await screen.findByText(MockUserAdminRole.display_name) - - // The attributes are "strings", not boolean types. - expect(owner.getAttribute("aria-disabled")).toBe("true") - expect(templateAdmin.getAttribute("aria-disabled")).toBe("true") - - expect(userAdmin.getAttribute("aria-disabled")).toBe("false") - expect(auditor.getAttribute("aria-disabled")).toBe("false") - }) -}) diff --git a/site/src/components/RoleSelect/RoleSelect.tsx b/site/src/components/RoleSelect/RoleSelect.tsx deleted file mode 100644 index 6a029a69456ae..0000000000000 --- a/site/src/components/RoleSelect/RoleSelect.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import Checkbox from "@material-ui/core/Checkbox" -import MenuItem from "@material-ui/core/MenuItem" -import Select from "@material-ui/core/Select" -import { makeStyles, Theme } from "@material-ui/core/styles" -import { FC } from "react" -import { AssignableRoles, Role } from "../../api/typesGenerated" - -export const Language = { - label: "Roles", -} -export interface RoleSelectProps { - roles: AssignableRoles[] - selectedRoles: Role[] - onChange: (roles: Role["name"][]) => void - loading?: boolean - open?: boolean -} - -export const RoleSelect: FC> = ({ - roles, - selectedRoles, - loading, - onChange, - open, -}) => { - const styles = useStyles() - const value = selectedRoles.map((r) => r.name) - const renderValue = () => selectedRoles.map((r) => r.display_name).join(", ") - const sortedRoles = roles.sort((a, b) => - a.display_name.localeCompare(b.display_name), - ) - - return ( - - ) -} - -const useStyles = makeStyles((theme: Theme) => ({ - select: { - margin: 0, - // Set a fixed width for the select. It avoids selects having different sizes - // depending on how many roles they have selected. - width: theme.spacing(32), - "& .MuiSelect-root": { - // Adjusting padding because it does not have label - paddingTop: theme.spacing(1.5), - paddingBottom: theme.spacing(1.5), - }, - }, -})) From a23b81879fdb2c0bd94dfad03d44962823aa3607 Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Wed, 4 Jan 2023 18:08:13 +0000 Subject: [PATCH 04/10] Update language --- site/src/i18n/en/usersPage.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/site/src/i18n/en/usersPage.json b/site/src/i18n/en/usersPage.json index 7fe06866309a8..5c092168aa9bd 100644 --- a/site/src/i18n/en/usersPage.json +++ b/site/src/i18n/en/usersPage.json @@ -8,11 +8,11 @@ "resetPasswordMenuItem": "Reset password", "editUserRolesTooltip": "Edit user roles", "roleDescription": { - "owner": "Admin can manage all the coder resources including users and their permissions", - "user-admin": "Admin can manage all the coder resources including users and their permissions", - "template-admin": "Admin can manage all the coder resources including users and their permissions", - "auditor": "Admin can manage all the coder resources including users and their permissions", - "member": "Admin can manage all the coder resources including users and their permissions" + "owner": "Owner can manage all the coder resources including users and their permissions", + "user-admin": "User admin can manage all the coder users and groups", + "template-admin": "Template admin can manage all the coder templates and permissions", + "auditor": "Auditor can access the audit logs", + "member": "Everybody is a member. This is a shared and default role for all the users" }, "member": "Member" } From 676d806ca364ee9e38de296dbdaa3bd597710064 Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Wed, 4 Jan 2023 18:21:01 +0000 Subject: [PATCH 05/10] Add storybooks --- .../EditRolesButton.stories.tsx | 31 +++++++++++++++++++ .../EditRolesButton/EditRolesButton.tsx | 15 +++++++-- site/src/theme/theme.ts | 8 +++++ 3 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 site/src/components/EditRolesButton/EditRolesButton.stories.tsx diff --git a/site/src/components/EditRolesButton/EditRolesButton.stories.tsx b/site/src/components/EditRolesButton/EditRolesButton.stories.tsx new file mode 100644 index 0000000000000..9c8eef5ccb0fe --- /dev/null +++ b/site/src/components/EditRolesButton/EditRolesButton.stories.tsx @@ -0,0 +1,31 @@ +import { ComponentMeta, Story } from "@storybook/react" +import { + MockOwnerRole, + MockSiteRoles, + MockUserAdminRole, +} from "testHelpers/entities" +import { EditRolesButtonProps, EditRolesButton } from "./EditRolesButton" + +export default { + title: "components/EditRolesButton", + component: EditRolesButton, +} as ComponentMeta + +const Template: Story = (args) => ( + +) + +export const Open = Template.bind({}) +Open.args = { + defaultIsOpen: true, + roles: MockSiteRoles, + selectedRoles: [MockUserAdminRole, MockOwnerRole], +} + +export const Loading = Template.bind({}) +Loading.args = { + defaultIsOpen: true, + roles: MockSiteRoles, + isLoading: true, + selectedRoles: [MockUserAdminRole, MockOwnerRole], +} diff --git a/site/src/components/EditRolesButton/EditRolesButton.tsx b/site/src/components/EditRolesButton/EditRolesButton.tsx index e8facc0f8968e..a252b6ceabf98 100644 --- a/site/src/components/EditRolesButton/EditRolesButton.tsx +++ b/site/src/components/EditRolesButton/EditRolesButton.tsx @@ -41,16 +41,25 @@ const Option: React.FC<{ ) } -export const EditRolesButton: FC<{ +export interface EditRolesButtonProps { isLoading: boolean roles: Role[] selectedRoles: Role[] onChange: (roles: Role["name"][]) => void -}> = ({ roles, selectedRoles, onChange, isLoading }) => { + defaultIsOpen?: boolean +} + +export const EditRolesButton: FC = ({ + roles, + selectedRoles, + onChange, + isLoading, + defaultIsOpen = false, +}) => { const styles = useStyles() const { t } = useTranslation("usersPage") const anchorRef = useRef(null) - const [isOpen, setIsOpen] = useState(false) + const [isOpen, setIsOpen] = useState(defaultIsOpen) const id = isOpen ? "edit-roles-popover" : undefined const selectedRoleNames = selectedRoles.map((role) => role.name) diff --git a/site/src/theme/theme.ts b/site/src/theme/theme.ts index fbb6ee63c0261..1fda4ea4b9c51 100644 --- a/site/src/theme/theme.ts +++ b/site/src/theme/theme.ts @@ -5,6 +5,7 @@ import { getOverrides } from "./overrides" import { darkPalette } from "./palettes" import { props } from "./props" import { typography } from "./typography" +import isChromatic from "chromatic/isChromatic" const makeTheme = (palette: PaletteOptions) => { const theme = createTheme({ @@ -16,6 +17,13 @@ const makeTheme = (palette: PaletteOptions) => { props, }) + // We want to disable transitions during chromatic snapshots + // https://www.chromatic.com/docs/animations#javascript-animations + // https://github.com/mui/material-ui/issues/10560#issuecomment-439147374 + if (isChromatic()) { + theme.transitions.create = () => "none" + } + theme.overrides = getOverrides(theme) return theme From 9b666f0c41855109b083d338e498e258628b6df0 Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Wed, 4 Jan 2023 18:38:42 +0000 Subject: [PATCH 06/10] Add delay --- .../components/EditRolesButton/EditRolesButton.stories.tsx | 6 ++++++ site/src/pages/UsersPage/UsersPage.test.tsx | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/site/src/components/EditRolesButton/EditRolesButton.stories.tsx b/site/src/components/EditRolesButton/EditRolesButton.stories.tsx index 9c8eef5ccb0fe..d1e60c16f1ac0 100644 --- a/site/src/components/EditRolesButton/EditRolesButton.stories.tsx +++ b/site/src/components/EditRolesButton/EditRolesButton.stories.tsx @@ -21,6 +21,9 @@ Open.args = { roles: MockSiteRoles, selectedRoles: [MockUserAdminRole, MockOwnerRole], } +Open.parameters = { + chromatic: { delay: 300 }, +} export const Loading = Template.bind({}) Loading.args = { @@ -29,3 +32,6 @@ Loading.args = { isLoading: true, selectedRoles: [MockUserAdminRole, MockOwnerRole], } +Loading.parameters = { + chromatic: { delay: 300 }, +} diff --git a/site/src/pages/UsersPage/UsersPage.test.tsx b/site/src/pages/UsersPage/UsersPage.test.tsx index f0e4fb35b7de9..bb1329ce48c7c 100644 --- a/site/src/pages/UsersPage/UsersPage.test.tsx +++ b/site/src/pages/UsersPage/UsersPage.test.tsx @@ -7,7 +7,6 @@ import * as API from "../../api/api" import { Role } from "../../api/typesGenerated" import { Language as ResetPasswordDialogLanguage } from "../../components/Dialogs/ResetPasswordDialog/ResetPasswordDialog" import { GlobalSnackbar } from "../../components/GlobalSnackbar/GlobalSnackbar" -import { Language as RoleSelectLanguage } from "../../components/RoleSelect/RoleSelect" import { MockAuditorRole, MockUser, From 2fe9e519a11fd53d04693fe7fed6c175ec309db3 Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Wed, 4 Jan 2023 16:20:15 -0300 Subject: [PATCH 07/10] Update site/src/i18n/en/usersPage.json Co-authored-by: Ben Potter --- site/src/i18n/en/usersPage.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/site/src/i18n/en/usersPage.json b/site/src/i18n/en/usersPage.json index 5c092168aa9bd..0eece290724b3 100644 --- a/site/src/i18n/en/usersPage.json +++ b/site/src/i18n/en/usersPage.json @@ -8,11 +8,11 @@ "resetPasswordMenuItem": "Reset password", "editUserRolesTooltip": "Edit user roles", "roleDescription": { - "owner": "Owner can manage all the coder resources including users and their permissions", - "user-admin": "User admin can manage all the coder users and groups", - "template-admin": "Template admin can manage all the coder templates and permissions", + "owner": "Owner can manage all resources, including users and their permissions", + "user-admin": "User admin can manage all users and groups", + "template-admin": "Template admin can manage all templates and permissions", "auditor": "Auditor can access the audit logs", - "member": "Everybody is a member. This is a shared and default role for all the users" + "member": "Everybody is a member. This is a shared and default role for all users" }, "member": "Member" } From 48cfb1df1a40f87342f663d63ce91d7f03b6c6e1 Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Wed, 4 Jan 2023 19:31:11 +0000 Subject: [PATCH 08/10] Fix test --- .../EditRolesButton.stories.tsx | 9 +++-- .../EditRolesButton/EditRolesButton.tsx | 6 +++- .../components/UsersTable/UsersTableBody.tsx | 8 ++--- site/src/i18n/en/usersPage.json | 1 + site/src/pages/UsersPage/UsersPage.test.tsx | 35 +++++++++---------- 5 files changed, 32 insertions(+), 27 deletions(-) diff --git a/site/src/components/EditRolesButton/EditRolesButton.stories.tsx b/site/src/components/EditRolesButton/EditRolesButton.stories.tsx index d1e60c16f1ac0..0323d3dcc60be 100644 --- a/site/src/components/EditRolesButton/EditRolesButton.stories.tsx +++ b/site/src/components/EditRolesButton/EditRolesButton.stories.tsx @@ -9,6 +9,11 @@ import { EditRolesButtonProps, EditRolesButton } from "./EditRolesButton" export default { title: "components/EditRolesButton", component: EditRolesButton, + argTypes: { + defaultIsOpen: { + defaultValue: true, + }, + }, } as ComponentMeta const Template: Story = (args) => ( @@ -17,7 +22,6 @@ const Template: Story = (args) => ( export const Open = Template.bind({}) Open.args = { - defaultIsOpen: true, roles: MockSiteRoles, selectedRoles: [MockUserAdminRole, MockOwnerRole], } @@ -27,9 +31,8 @@ Open.parameters = { export const Loading = Template.bind({}) Loading.args = { - defaultIsOpen: true, - roles: MockSiteRoles, isLoading: true, + roles: MockSiteRoles, selectedRoles: [MockUserAdminRole, MockOwnerRole], } Loading.parameters = { diff --git a/site/src/components/EditRolesButton/EditRolesButton.tsx b/site/src/components/EditRolesButton/EditRolesButton.tsx index a252b6ceabf98..0683916fa8353 100644 --- a/site/src/components/EditRolesButton/EditRolesButton.tsx +++ b/site/src/components/EditRolesButton/EditRolesButton.tsx @@ -99,7 +99,11 @@ export const EditRolesButton: FC = ({ }} classes={{ paper: styles.popoverPaper }} > -
+
{roles.map((role) => (