mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix: migrate <TemplatePermissionsPageView /> out of mui (#22363)
This pull-request migrates `<TemplatePermissionsPageView />` out of using MUI components. Using proper selects that are inline with the rest of the codebase. | Old | New | | --- | --- | | <img width="1030" height="284" alt="OLD_TEMPLATE_PERMISSIONS" src="https://github.com/user-attachments/assets/778e983b-7ac1-4429-87ca-6107b176a762" /> | <img width="1030" height="283" alt="NEW_TEMPLATE_PERMISSIONS" src="https://github.com/user-attachments/assets/f7acf3c7-0cbd-4433-adc1-7ba7f44f3fe2" /> |
This commit is contained in:
+59
-89
@@ -1,6 +1,3 @@
|
||||
import type { Interpolation, Theme } from "@emotion/react";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import Select, { type SelectProps } from "@mui/material/Select";
|
||||
import type {
|
||||
Group,
|
||||
ReducedUser,
|
||||
@@ -21,8 +18,14 @@ import {
|
||||
} from "components/DropdownMenu/DropdownMenu";
|
||||
import { EmptyState } from "components/EmptyState/EmptyState";
|
||||
import { PageHeader, PageHeaderTitle } from "components/PageHeader/PageHeader";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "components/Select/Select";
|
||||
import { Spinner } from "components/Spinner/Spinner";
|
||||
import { Stack } from "components/Stack/Stack";
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
@@ -90,7 +93,7 @@ const AddTemplateUserOrGroup: FC<AddTemplateUserOrGroupProps> = ({
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Stack direction="row" alignItems="center" spacing={1}>
|
||||
<div className="flex flex-row items-center gap-1">
|
||||
<UserOrGroupAutocomplete
|
||||
exclude={excludeFromAutocomplete}
|
||||
templateID={templateID}
|
||||
@@ -101,20 +104,19 @@ const AddTemplateUserOrGroup: FC<AddTemplateUserOrGroupProps> = ({
|
||||
/>
|
||||
|
||||
<Select
|
||||
defaultValue="use"
|
||||
size="small"
|
||||
css={styles.select}
|
||||
value={selectedRole}
|
||||
disabled={isLoading}
|
||||
onChange={(event) => {
|
||||
setSelectedRole(event.target.value as TemplateRole);
|
||||
onValueChange={(value) => {
|
||||
setSelectedRole(value as TemplateRole);
|
||||
}}
|
||||
>
|
||||
<MenuItem key="use" value="use">
|
||||
Use
|
||||
</MenuItem>
|
||||
<MenuItem key="admin" value="admin">
|
||||
Admin
|
||||
</MenuItem>
|
||||
<SelectTrigger className="w-[100px]">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="use">Use</SelectItem>
|
||||
<SelectItem value="admin">Admin</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
<Button
|
||||
@@ -126,35 +128,51 @@ const AddTemplateUserOrGroup: FC<AddTemplateUserOrGroupProps> = ({
|
||||
</Spinner>
|
||||
Add member
|
||||
</Button>
|
||||
</Stack>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
const RoleSelect: FC<SelectProps> = (props) => {
|
||||
interface RoleSelectProps {
|
||||
value: TemplateRole;
|
||||
disabled?: boolean;
|
||||
onValueChange: (value: TemplateRole) => void;
|
||||
}
|
||||
|
||||
const RoleSelect: FC<RoleSelectProps> = ({
|
||||
value,
|
||||
disabled,
|
||||
onValueChange,
|
||||
}) => {
|
||||
return (
|
||||
<Select
|
||||
renderValue={(value) => <div css={styles.role}>{`${value}`}</div>}
|
||||
css={styles.updateSelect}
|
||||
{...props}
|
||||
value={value}
|
||||
disabled={disabled}
|
||||
onValueChange={(nextValue) => onValueChange(nextValue as TemplateRole)}
|
||||
>
|
||||
<MenuItem key="use" value="use" css={styles.menuItem}>
|
||||
<div>
|
||||
<div>Use</div>
|
||||
<div css={styles.menuItemSecondary}>
|
||||
<SelectTrigger className="h-auto w-[200px]">
|
||||
<SelectValue>
|
||||
<span className="capitalize">{value}</span>
|
||||
</SelectValue>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="use" className="w-[250px] flex-col items-start py-2">
|
||||
<div className="text-content-primary">Use</div>
|
||||
<div className="text-xs leading-[140%] text-content-secondary">
|
||||
Can read and use this template to create workspaces.
|
||||
</div>
|
||||
</div>
|
||||
</MenuItem>
|
||||
<MenuItem key="admin" value="admin" css={styles.menuItem}>
|
||||
<div>
|
||||
<div>Admin</div>
|
||||
<div css={styles.menuItemSecondary}>
|
||||
</SelectItem>
|
||||
<SelectItem
|
||||
value="admin"
|
||||
className="w-[250px] flex-col items-start py-2"
|
||||
>
|
||||
<div className="text-content-primary">Admin</div>
|
||||
<div className="text-xs leading-[140%] text-content-secondary">
|
||||
Can modify all aspects of this template including permissions,
|
||||
metadata, and template versions.
|
||||
</div>
|
||||
</div>
|
||||
</MenuItem>
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
);
|
||||
};
|
||||
@@ -216,7 +234,7 @@ export const TemplatePermissionsPageView: FC<
|
||||
<PageHeaderTitle>Permissions</PageHeaderTitle>
|
||||
</PageHeader>
|
||||
|
||||
<Stack spacing={2.5}>
|
||||
<div className="flex flex-col gap-2.5">
|
||||
{canUpdatePermissions && (
|
||||
<AddTemplateUserOrGroup
|
||||
templateACL={templateACL}
|
||||
@@ -274,16 +292,13 @@ export const TemplatePermissionsPageView: FC<
|
||||
<RoleSelect
|
||||
value={group.role}
|
||||
disabled={updatingGroupId === group.id}
|
||||
onChange={(event) => {
|
||||
onUpdateGroup(
|
||||
group,
|
||||
event.target.value as TemplateRole,
|
||||
);
|
||||
onValueChange={(role) => {
|
||||
onUpdateGroup(group, role);
|
||||
}}
|
||||
/>
|
||||
</Cond>
|
||||
<Cond>
|
||||
<div css={styles.role}>{group.role}</div>
|
||||
<div className="capitalize">{group.role}</div>
|
||||
</Cond>
|
||||
</ChooseOne>
|
||||
</TableCell>
|
||||
@@ -330,16 +345,13 @@ export const TemplatePermissionsPageView: FC<
|
||||
<RoleSelect
|
||||
value={user.role}
|
||||
disabled={updatingUserId === user.id}
|
||||
onChange={(event) => {
|
||||
onUpdateUser(
|
||||
user,
|
||||
event.target.value as TemplateRole,
|
||||
);
|
||||
onValueChange={(role) => {
|
||||
onUpdateUser(user, role);
|
||||
}}
|
||||
/>
|
||||
</Cond>
|
||||
<Cond>
|
||||
<div css={styles.role}>{user.role}</div>
|
||||
<div className="capitalize">{user.role}</div>
|
||||
</Cond>
|
||||
</ChooseOne>
|
||||
</TableCell>
|
||||
@@ -374,49 +386,7 @@ export const TemplatePermissionsPageView: FC<
|
||||
</ChooseOne>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</Stack>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = {
|
||||
select: {
|
||||
// Match button small height
|
||||
fontSize: 14,
|
||||
width: 100,
|
||||
},
|
||||
|
||||
updateSelect: {
|
||||
margin: 0,
|
||||
// Set a fixed width for the select. It avoids selects having different sizes
|
||||
// depending on how many roles they have selected.
|
||||
width: 200,
|
||||
|
||||
"& .MuiSelect-root": {
|
||||
// Adjusting padding because it does not have label
|
||||
paddingTop: 12,
|
||||
paddingBottom: 12,
|
||||
|
||||
".secondary": {
|
||||
display: "none",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
role: {
|
||||
textTransform: "capitalize",
|
||||
},
|
||||
|
||||
menuItem: {
|
||||
lineHeight: "140%",
|
||||
paddingTop: 12,
|
||||
paddingBottom: 12,
|
||||
whiteSpace: "normal",
|
||||
inlineSize: "250px",
|
||||
},
|
||||
|
||||
menuItemSecondary: (theme) => ({
|
||||
fontSize: 14,
|
||||
color: theme.palette.text.secondary,
|
||||
}),
|
||||
} satisfies Record<string, Interpolation<Theme>>;
|
||||
|
||||
Reference in New Issue
Block a user