mirror of
https://github.com/coder/coder.git
synced 2025-03-14 10:09:57 +00:00
chore: migrate settings page tables from mui to shadcn (#16896)
Custom Roles <img width="795" alt="Screenshot 2025-03-12 at 21 04 53" src="https://github.com/user-attachments/assets/d478e80d-6d11-496c-a37f-87a73a5587b7" /> Group Page <img width="804" alt="Screenshot 2025-03-12 at 21 04 12" src="https://github.com/user-attachments/assets/eec9749a-7a34-42ca-97a8-c2a624f766bb" /> Groups Page <img width="802" alt="Screenshot 2025-03-12 at 21 04 06" src="https://github.com/user-attachments/assets/7b88f6ab-9364-4e15-b969-8e422b24085c" /> Users Page <img width="820" alt="Screenshot 2025-03-12 at 21 03 58" src="https://github.com/user-attachments/assets/195dea6e-c57f-4155-8d71-3adc3a6202bc" />
This commit is contained in:
site
e2e/tests
src/pages
DeploymentSettingsPage/IdpOrgSyncPage
GroupsPage
OrganizationSettingsPage
UsersPage/UsersTable
@ -105,8 +105,9 @@ test("change quota settings", async ({ page }) => {
|
||||
// Go to settings
|
||||
await login(page, orgUserAdmin);
|
||||
await page.goto(`/organizations/${org.name}/groups/${group.name}`);
|
||||
await page.getByRole("button", { name: "Settings", exact: true }).click();
|
||||
expectUrl(page).toHavePathName(
|
||||
|
||||
await page.getByRole("link", { name: "Settings", exact: true }).click();
|
||||
await expectUrl(page).toHavePathName(
|
||||
`/organizations/${org.name}/groups/${group.name}/settings`,
|
||||
);
|
||||
|
||||
@ -115,11 +116,11 @@ test("change quota settings", async ({ page }) => {
|
||||
await page.getByRole("button", { name: /save/i }).click();
|
||||
|
||||
// We should get sent back to the group page afterwards
|
||||
expectUrl(page).toHavePathName(
|
||||
await expectUrl(page).toHavePathName(
|
||||
`/organizations/${org.name}/groups/${group.name}`,
|
||||
);
|
||||
|
||||
// ...and that setting should persist if we go back
|
||||
await page.getByRole("button", { name: "Settings", exact: true }).click();
|
||||
await page.getByRole("link", { name: "Settings", exact: true }).click();
|
||||
await expect(page.getByLabel("Quota Allowance")).toHaveValue("100");
|
||||
});
|
||||
|
@ -34,6 +34,7 @@ import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "components/Table/Table";
|
||||
@ -365,9 +366,9 @@ const IdpMappingTable: FC<IdpMappingTableProps> = ({ isEmpty, children }) => {
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableCell width="45%">IdP organization</TableCell>
|
||||
<TableCell width="55%">Coder organization</TableCell>
|
||||
<TableCell width="5%" />
|
||||
<TableHead className="w-2/5">IdP organization</TableHead>
|
||||
<TableHead className="w-3/5">Coder organization</TableHead>
|
||||
<TableHead className="w-auto" />
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
|
@ -4,12 +4,6 @@ import PersonAdd from "@mui/icons-material/PersonAdd";
|
||||
import SettingsOutlined from "@mui/icons-material/SettingsOutlined";
|
||||
import LoadingButton from "@mui/lab/LoadingButton";
|
||||
import Button from "@mui/material/Button";
|
||||
import Table from "@mui/material/Table";
|
||||
import TableBody from "@mui/material/TableBody";
|
||||
import TableCell from "@mui/material/TableCell";
|
||||
import TableContainer from "@mui/material/TableContainer";
|
||||
import TableHead from "@mui/material/TableHead";
|
||||
import TableRow from "@mui/material/TableRow";
|
||||
import { getErrorMessage } from "api/errors";
|
||||
import {
|
||||
addMember,
|
||||
@ -40,6 +34,14 @@ import {
|
||||
} from "components/MoreMenu/MoreMenu";
|
||||
import { SettingsHeader } from "components/SettingsHeader/SettingsHeader";
|
||||
import { Stack } from "components/Stack/Stack";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "components/Table/Table";
|
||||
import {
|
||||
PaginationStatus,
|
||||
TableToolbar,
|
||||
@ -111,7 +113,6 @@ export const GroupPage: FC = () => {
|
||||
{canUpdateGroup && (
|
||||
<Stack direction="row" spacing={2}>
|
||||
<Button
|
||||
role="button"
|
||||
component={RouterLink}
|
||||
startIcon={<SettingsOutlined />}
|
||||
to="settings"
|
||||
@ -160,53 +161,51 @@ export const GroupPage: FC = () => {
|
||||
/>
|
||||
</TableToolbar>
|
||||
|
||||
<TableContainer>
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell width="59%">User</TableCell>
|
||||
<TableCell width="40">Status</TableCell>
|
||||
<TableCell width="1%" />
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead className="w-2/5">User</TableHead>
|
||||
<TableHead className="w-3/5">Status</TableHead>
|
||||
<TableHead className="w-auto" />
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
|
||||
<TableBody>
|
||||
{groupData?.members.length === 0 ? (
|
||||
<TableRow>
|
||||
<TableCell colSpan={999}>
|
||||
<EmptyState
|
||||
message="No members yet"
|
||||
description="Add a member using the controls above"
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : (
|
||||
groupData?.members.map((member) => (
|
||||
<GroupMemberRow
|
||||
member={member}
|
||||
group={groupData}
|
||||
key={member.id}
|
||||
canUpdate={canUpdateGroup}
|
||||
onRemove={async () => {
|
||||
try {
|
||||
await removeMemberMutation.mutateAsync({
|
||||
groupId: groupData.id,
|
||||
userId: member.id,
|
||||
});
|
||||
await groupQuery.refetch();
|
||||
displaySuccess("Member removed successfully.");
|
||||
} catch (error) {
|
||||
displayError(
|
||||
getErrorMessage(error, "Failed to remove member."),
|
||||
);
|
||||
}
|
||||
}}
|
||||
<TableBody>
|
||||
{groupData?.members.length === 0 ? (
|
||||
<TableRow>
|
||||
<TableCell colSpan={999}>
|
||||
<EmptyState
|
||||
message="No members yet"
|
||||
description="Add a member using the controls above"
|
||||
/>
|
||||
))
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : (
|
||||
groupData?.members.map((member) => (
|
||||
<GroupMemberRow
|
||||
member={member}
|
||||
group={groupData}
|
||||
key={member.id}
|
||||
canUpdate={canUpdateGroup}
|
||||
onRemove={async () => {
|
||||
try {
|
||||
await removeMemberMutation.mutateAsync({
|
||||
groupId: groupData.id,
|
||||
userId: member.id,
|
||||
});
|
||||
await groupQuery.refetch();
|
||||
displaySuccess("Member removed successfully.");
|
||||
} catch (error) {
|
||||
displayError(
|
||||
getErrorMessage(error, "Failed to remove member."),
|
||||
);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
))
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</Stack>
|
||||
|
||||
{groupQuery.data && (
|
||||
|
@ -3,12 +3,6 @@ import AddOutlined from "@mui/icons-material/AddOutlined";
|
||||
import KeyboardArrowRight from "@mui/icons-material/KeyboardArrowRight";
|
||||
import AvatarGroup from "@mui/material/AvatarGroup";
|
||||
import Skeleton from "@mui/material/Skeleton";
|
||||
import Table from "@mui/material/Table";
|
||||
import TableBody from "@mui/material/TableBody";
|
||||
import TableCell from "@mui/material/TableCell";
|
||||
import TableContainer from "@mui/material/TableContainer";
|
||||
import TableHead from "@mui/material/TableHead";
|
||||
import TableRow from "@mui/material/TableRow";
|
||||
import type { Group } from "api/typesGenerated";
|
||||
import { Avatar } from "components/Avatar/Avatar";
|
||||
import { AvatarData } from "components/Avatar/AvatarData";
|
||||
@ -17,6 +11,14 @@ import { Button } from "components/Button/Button";
|
||||
import { ChooseOne, Cond } from "components/Conditionals/ChooseOne";
|
||||
import { EmptyState } from "components/EmptyState/EmptyState";
|
||||
import { Paywall } from "components/Paywall/Paywall";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "components/Table/Table";
|
||||
import {
|
||||
TableLoaderSkeleton,
|
||||
TableRowSkeleton,
|
||||
@ -51,55 +53,53 @@ export const GroupsPageView: FC<GroupsPageViewProps> = ({
|
||||
/>
|
||||
</Cond>
|
||||
<Cond>
|
||||
<TableContainer>
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell width="50%">Name</TableCell>
|
||||
<TableCell width="49%">Users</TableCell>
|
||||
<TableCell width="1%" />
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<ChooseOne>
|
||||
<Cond condition={isLoading}>
|
||||
<TableLoader />
|
||||
</Cond>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead className="w-2/5">Name</TableHead>
|
||||
<TableHead className="w-3/5">Users</TableHead>
|
||||
<TableHead className="w-auto" />
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
<ChooseOne>
|
||||
<Cond condition={isLoading}>
|
||||
<TableLoader />
|
||||
</Cond>
|
||||
|
||||
<Cond condition={isEmpty}>
|
||||
<TableRow>
|
||||
<TableCell colSpan={999}>
|
||||
<EmptyState
|
||||
message="No groups yet"
|
||||
description={
|
||||
canCreateGroup
|
||||
? "Create your first group"
|
||||
: "You don't have permission to create a group"
|
||||
}
|
||||
cta={
|
||||
canCreateGroup && (
|
||||
<Button asChild>
|
||||
<RouterLink to="create">
|
||||
<AddOutlined />
|
||||
Create group
|
||||
</RouterLink>
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</Cond>
|
||||
<Cond condition={isEmpty}>
|
||||
<TableRow>
|
||||
<TableCell colSpan={999}>
|
||||
<EmptyState
|
||||
message="No groups yet"
|
||||
description={
|
||||
canCreateGroup
|
||||
? "Create your first group"
|
||||
: "You don't have permission to create a group"
|
||||
}
|
||||
cta={
|
||||
canCreateGroup && (
|
||||
<Button asChild>
|
||||
<RouterLink to="create">
|
||||
<AddOutlined />
|
||||
Create group
|
||||
</RouterLink>
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</Cond>
|
||||
|
||||
<Cond>
|
||||
{groups?.map((group) => (
|
||||
<GroupRow key={group.id} group={group} />
|
||||
))}
|
||||
</Cond>
|
||||
</ChooseOne>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
<Cond>
|
||||
{groups?.map((group) => (
|
||||
<GroupRow key={group.id} group={group} />
|
||||
))}
|
||||
</Cond>
|
||||
</ChooseOne>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</Cond>
|
||||
</ChooseOne>
|
||||
</>
|
||||
|
@ -3,12 +3,6 @@ import AddIcon from "@mui/icons-material/AddOutlined";
|
||||
import AddOutlined from "@mui/icons-material/AddOutlined";
|
||||
import Button from "@mui/material/Button";
|
||||
import Skeleton from "@mui/material/Skeleton";
|
||||
import Table from "@mui/material/Table";
|
||||
import TableBody from "@mui/material/TableBody";
|
||||
import TableCell from "@mui/material/TableCell";
|
||||
import TableContainer from "@mui/material/TableContainer";
|
||||
import TableHead from "@mui/material/TableHead";
|
||||
import TableRow from "@mui/material/TableRow";
|
||||
import type { AssignableRoles, Role } from "api/typesGenerated";
|
||||
import { ChooseOne, Cond } from "components/Conditionals/ChooseOne";
|
||||
import { EmptyState } from "components/EmptyState/EmptyState";
|
||||
@ -21,6 +15,14 @@ import {
|
||||
} from "components/MoreMenu/MoreMenu";
|
||||
import { Paywall } from "components/Paywall/Paywall";
|
||||
import { Stack } from "components/Stack/Stack";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "components/Table/Table";
|
||||
import {
|
||||
TableLoaderSkeleton,
|
||||
TableRowSkeleton,
|
||||
@ -123,68 +125,66 @@ const RoleTable: FC<RoleTableProps> = ({
|
||||
const isLoading = roles === undefined;
|
||||
const isEmpty = Boolean(roles && roles.length === 0);
|
||||
return (
|
||||
<TableContainer>
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell width="40%">Name</TableCell>
|
||||
<TableCell width="59%">Permissions</TableCell>
|
||||
<TableCell width="1%" />
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
<ChooseOne>
|
||||
<Cond condition={isLoading}>
|
||||
<TableLoader />
|
||||
</Cond>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead className="w-2/5">Name</TableHead>
|
||||
<TableHead className="w-3/5">Permissions</TableHead>
|
||||
<TableHead className="w-auto" />
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
<ChooseOne>
|
||||
<Cond condition={isLoading}>
|
||||
<TableLoader />
|
||||
</Cond>
|
||||
|
||||
<Cond condition={isEmpty}>
|
||||
<TableRow>
|
||||
<TableCell colSpan={999}>
|
||||
<EmptyState
|
||||
message="No custom roles yet"
|
||||
description={
|
||||
canCreateOrgRole && isCustomRolesEnabled
|
||||
? "Create your first custom role"
|
||||
: !isCustomRolesEnabled
|
||||
? "Upgrade to a premium license to create a custom role"
|
||||
: "You don't have permission to create a custom role"
|
||||
}
|
||||
cta={
|
||||
canCreateOrgRole &&
|
||||
isCustomRolesEnabled && (
|
||||
<Button
|
||||
component={RouterLink}
|
||||
to="create"
|
||||
startIcon={<AddOutlined />}
|
||||
variant="contained"
|
||||
>
|
||||
Create custom role
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</Cond>
|
||||
<Cond condition={isEmpty}>
|
||||
<TableRow className="h-14">
|
||||
<TableCell colSpan={999}>
|
||||
<EmptyState
|
||||
message="No custom roles yet"
|
||||
description={
|
||||
canCreateOrgRole && isCustomRolesEnabled
|
||||
? "Create your first custom role"
|
||||
: !isCustomRolesEnabled
|
||||
? "Upgrade to a premium license to create a custom role"
|
||||
: "You don't have permission to create a custom role"
|
||||
}
|
||||
cta={
|
||||
canCreateOrgRole &&
|
||||
isCustomRolesEnabled && (
|
||||
<Button
|
||||
component={RouterLink}
|
||||
to="create"
|
||||
startIcon={<AddOutlined />}
|
||||
variant="contained"
|
||||
>
|
||||
Create custom role
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</Cond>
|
||||
|
||||
<Cond>
|
||||
{roles
|
||||
?.sort((a, b) => a.name.localeCompare(b.name))
|
||||
.map((role) => (
|
||||
<RoleRow
|
||||
key={role.name}
|
||||
role={role}
|
||||
canUpdateOrgRole={canUpdateOrgRole}
|
||||
canDeleteOrgRole={canDeleteOrgRole}
|
||||
onDelete={() => onDeleteRole(role)}
|
||||
/>
|
||||
))}
|
||||
</Cond>
|
||||
</ChooseOne>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
<Cond>
|
||||
{roles
|
||||
?.sort((a, b) => a.name.localeCompare(b.name))
|
||||
.map((role) => (
|
||||
<RoleRow
|
||||
key={role.name}
|
||||
role={role}
|
||||
canUpdateOrgRole={canUpdateOrgRole}
|
||||
canDeleteOrgRole={canDeleteOrgRole}
|
||||
onDelete={() => onDeleteRole(role)}
|
||||
/>
|
||||
))}
|
||||
</Cond>
|
||||
</ChooseOne>
|
||||
</TableBody>
|
||||
</Table>
|
||||
);
|
||||
};
|
||||
|
||||
@ -204,7 +204,7 @@ const RoleRow: FC<RoleRowProps> = ({
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<TableRow data-testid={`role-${role.name}`}>
|
||||
<TableRow data-testid={`role-${role.name}`} className="h-14">
|
||||
<TableCell>{role.display_name || role.name}</TableCell>
|
||||
|
||||
<TableCell>
|
||||
|
@ -27,9 +27,13 @@ export const IdpMappingTable: FC<IdpMappingTableProps> = ({
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableCell width="45%">IdP {type.toLocaleLowerCase()}</TableCell>
|
||||
<TableCell width="55%">Coder {type.toLocaleLowerCase()}</TableCell>
|
||||
<TableCell width="5%" />
|
||||
<TableCell className="w-2/5">
|
||||
IdP {type.toLocaleLowerCase()}
|
||||
</TableCell>
|
||||
<TableCell className="w-3/5">
|
||||
Coder {type.toLocaleLowerCase()}
|
||||
</TableCell>
|
||||
<TableCell className="w-auto" />
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
|
@ -24,6 +24,7 @@ import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "components/Table/Table";
|
||||
@ -95,20 +96,20 @@ export const OrganizationMembersPageView: FC<
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableCell width="33%">User</TableCell>
|
||||
<TableCell width="33%">
|
||||
<TableHead className="w-2/6">User</TableHead>
|
||||
<TableHead className="w-2/6">
|
||||
<Stack direction="row" spacing={1} alignItems="center">
|
||||
<span>Roles</span>
|
||||
<TableColumnHelpTooltip variant="roles" />
|
||||
</Stack>
|
||||
</TableCell>
|
||||
<TableCell width="33%">
|
||||
</TableHead>
|
||||
<TableHead className="w-2/6">
|
||||
<Stack direction="row" spacing={1} alignItems="center">
|
||||
<span>Groups</span>
|
||||
<TableColumnHelpTooltip variant="groups" />
|
||||
</Stack>
|
||||
</TableCell>
|
||||
<TableCell width="1%" />
|
||||
</TableHead>
|
||||
<TableHead className="w-auto" />
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
|
@ -1,12 +1,13 @@
|
||||
import Table from "@mui/material/Table";
|
||||
import TableBody from "@mui/material/TableBody";
|
||||
import TableCell from "@mui/material/TableCell";
|
||||
import TableContainer from "@mui/material/TableContainer";
|
||||
import TableHead from "@mui/material/TableHead";
|
||||
import TableRow from "@mui/material/TableRow";
|
||||
import type { GroupsByUserId } from "api/queries/groups";
|
||||
import type * as TypesGen from "api/typesGenerated";
|
||||
import { Stack } from "components/Stack/Stack";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "components/Table/Table";
|
||||
import type { FC } from "react";
|
||||
import { TableColumnHelpTooltip } from "../../OrganizationSettingsPage/UserTable/TableColumnHelpTooltip";
|
||||
import { UsersTableBody } from "./UsersTableBody";
|
||||
@ -65,57 +66,50 @@ export const UsersTable: FC<UsersTableProps> = ({
|
||||
groupsByUserId,
|
||||
}) => {
|
||||
return (
|
||||
<TableContainer>
|
||||
<Table data-testid="users-table">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell width="32%">{Language.usernameLabel}</TableCell>
|
||||
<Table data-testid="users-table">
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead className="w-2/6">{Language.usernameLabel}</TableHead>
|
||||
<TableHead className="w-2/6">
|
||||
<Stack direction="row" spacing={1} alignItems="center">
|
||||
<span>{Language.rolesLabel}</span>
|
||||
<TableColumnHelpTooltip variant="roles" />
|
||||
</Stack>
|
||||
</TableHead>
|
||||
<TableHead className="w-1/6">
|
||||
<Stack direction="row" spacing={1} alignItems="center">
|
||||
<span>{Language.groupsLabel}</span>
|
||||
<TableColumnHelpTooltip variant="groups" />
|
||||
</Stack>
|
||||
</TableHead>
|
||||
<TableHead className="w-1/6">{Language.loginTypeLabel}</TableHead>
|
||||
<TableHead className="w-1/6">{Language.statusLabel}</TableHead>
|
||||
{canEditUsers && <TableHead className="w-auto" />}
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
|
||||
<TableCell width="29%">
|
||||
<Stack direction="row" spacing={1} alignItems="center">
|
||||
<span>{Language.rolesLabel}</span>
|
||||
<TableColumnHelpTooltip variant="roles" />
|
||||
</Stack>
|
||||
</TableCell>
|
||||
|
||||
<TableCell width="13%">
|
||||
<Stack direction="row" spacing={1} alignItems="center">
|
||||
<span>{Language.groupsLabel}</span>
|
||||
<TableColumnHelpTooltip variant="groups" />
|
||||
</Stack>
|
||||
</TableCell>
|
||||
|
||||
<TableCell width="13%">{Language.loginTypeLabel}</TableCell>
|
||||
<TableCell width="13%">{Language.statusLabel}</TableCell>
|
||||
|
||||
{/* 1% is a trick to make the table cell width fit the content */}
|
||||
{canEditUsers && <TableCell width="1%" />}
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
|
||||
<TableBody>
|
||||
<UsersTableBody
|
||||
users={users}
|
||||
roles={roles}
|
||||
groupsByUserId={groupsByUserId}
|
||||
isLoading={isLoading}
|
||||
canEditUsers={canEditUsers}
|
||||
canViewActivity={canViewActivity}
|
||||
isUpdatingUserRoles={isUpdatingUserRoles}
|
||||
onActivateUser={onActivateUser}
|
||||
onDeleteUser={onDeleteUser}
|
||||
onListWorkspaces={onListWorkspaces}
|
||||
onViewActivity={onViewActivity}
|
||||
onResetUserPassword={onResetUserPassword}
|
||||
onSuspendUser={onSuspendUser}
|
||||
onUpdateUserRoles={onUpdateUserRoles}
|
||||
isNonInitialPage={isNonInitialPage}
|
||||
actorID={actorID}
|
||||
oidcRoleSyncEnabled={oidcRoleSyncEnabled}
|
||||
authMethods={authMethods}
|
||||
/>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
<TableBody>
|
||||
<UsersTableBody
|
||||
users={users}
|
||||
roles={roles}
|
||||
groupsByUserId={groupsByUserId}
|
||||
isLoading={isLoading}
|
||||
canEditUsers={canEditUsers}
|
||||
canViewActivity={canViewActivity}
|
||||
isUpdatingUserRoles={isUpdatingUserRoles}
|
||||
onActivateUser={onActivateUser}
|
||||
onDeleteUser={onDeleteUser}
|
||||
onListWorkspaces={onListWorkspaces}
|
||||
onViewActivity={onViewActivity}
|
||||
onResetUserPassword={onResetUserPassword}
|
||||
onSuspendUser={onSuspendUser}
|
||||
onUpdateUserRoles={onUpdateUserRoles}
|
||||
isNonInitialPage={isNonInitialPage}
|
||||
actorID={actorID}
|
||||
oidcRoleSyncEnabled={oidcRoleSyncEnabled}
|
||||
authMethods={authMethods}
|
||||
/>
|
||||
</TableBody>
|
||||
</Table>
|
||||
);
|
||||
};
|
||||
|
@ -6,8 +6,6 @@ import PasswordOutlined from "@mui/icons-material/PasswordOutlined";
|
||||
import ShieldOutlined from "@mui/icons-material/ShieldOutlined";
|
||||
import Divider from "@mui/material/Divider";
|
||||
import Skeleton from "@mui/material/Skeleton";
|
||||
import TableCell from "@mui/material/TableCell";
|
||||
import TableRow from "@mui/material/TableRow";
|
||||
import type { GroupsByUserId } from "api/queries/groups";
|
||||
import type * as TypesGen from "api/typesGenerated";
|
||||
import { AvatarData } from "components/Avatar/AvatarData";
|
||||
@ -23,6 +21,7 @@ import {
|
||||
MoreMenuTrigger,
|
||||
ThreeDotsButton,
|
||||
} from "components/MoreMenu/MoreMenu";
|
||||
import { TableCell, TableRow } from "components/Table/Table";
|
||||
import {
|
||||
TableLoaderSkeleton,
|
||||
TableRowSkeleton,
|
||||
|
Reference in New Issue
Block a user