Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita39bca5

Browse files
committed
feat: wip
1 parent019da85 commita39bca5

File tree

4 files changed

+116
-50
lines changed

4 files changed

+116
-50
lines changed

‎enterprise/coderd/roles.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,12 @@ func (h enterpriseCustomRoleHandler) PatchOrganizationRole(ctx context.Context,
7878
}
7979

8080
ifrole.OrganizationID!=orgID.String() {
81-
httpapi.Write(ctx,rw,http.StatusBadRequest, codersdk.Response{
82-
Message:"Invalid request, organization in role and url must match",
83-
Detail:fmt.Sprintf("role organization=%q does not match URL=%q",role.OrganizationID,orgID.String()),
84-
})
85-
return codersdk.Role{},false
81+
// httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
82+
// Message: "Invalid request, organization in role and url must match",
83+
// Detail: fmt.Sprintf("role organization=%q does not match URL=%q", role.OrganizationID, orgID.String()),
84+
// })
85+
// return codersdk.Role{}, false
86+
role.OrganizationID=orgID.String()
8687
}
8788

8889
originalRoles,err:=db.CustomRoles(ctx, database.CustomRolesParams{

‎site/src/pages/ManagementSettingsPage/CustomRolesPage/CreateEditRolePage.tsx

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,47 @@
11
importtype{FC}from"react";
22
import{Helmet}from"react-helmet-async";
3-
import{useMutation,useQueryClient}from"react-query";
3+
import{useMutation,useQuery,useQueryClient}from"react-query";
44
import{useNavigate,useParams}from"react-router-dom";
5-
import{patchOrganizationRole}from"api/queries/roles";
5+
import{getErrorMessage}from"api/errors";
6+
import{patchOrganizationRole,organizationRoles}from"api/queries/roles";
7+
import{displayError}from"components/GlobalSnackbar/utils";
68
import{pageTitle}from"utils/page";
79
importCreateEditRolePageViewfrom"./CreateEditRolePageView";
810

911
exportconstCreateGroupPage:FC=()=>{
1012
constqueryClient=useQueryClient();
1113
constnavigate=useNavigate();
12-
const{ organization}=useParams()as{organization:string};
14+
const{ organization, roleName}=useParams()as{
15+
organization:string;
16+
roleName:string;
17+
};
1318
constpatchOrganizationRoleMutation=useMutation(
1419
patchOrganizationRole(queryClient,organization??"default"),
1520
);
21+
const{ data}=useQuery(organizationRoles(organization));
22+
constrole=data?.find((role)=>role.name===roleName);
23+
constpageTitleText=
24+
role!==undefined ?"Edit Custom Role" :"Create Custom Role";
1625

1726
return(
1827
<>
1928
<Helmet>
20-
<title>{pageTitle("Create Custom Role")}</title>
29+
<title>{pageTitle(pageTitleText)}</title>
2130
</Helmet>
2231
<CreateEditRolePageView
32+
role={role}
33+
organization={organization}
2334
onSubmit={async(data)=>{
24-
constnewRole=awaitpatchOrganizationRoleMutation.mutateAsync(data);
25-
console.log({ newRole});
26-
navigate(`/organizations/${organization}/roles`);
35+
try{
36+
console.log({ data});
37+
awaitpatchOrganizationRoleMutation.mutateAsync(data);
38+
navigate(`/organizations/${organization}/roles`);
39+
}catch(error){
40+
console.log({ error});
41+
displayError(
42+
getErrorMessage(error,"Failed to update custom role"),
43+
);
44+
}
2745
}}
2846
error={patchOrganizationRoleMutation.error}
2947
isLoading={patchOrganizationRoleMutation.isLoading}

‎site/src/pages/ManagementSettingsPage/CustomRolesPage/CreateEditRolePageView.tsx

Lines changed: 80 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
importtype{Interpolation,Theme}from"@emotion/react";
2+
importCheckboxfrom"@mui/material/Checkbox";
23
importTablefrom"@mui/material/Table";
34
importTableBodyfrom"@mui/material/TableBody";
45
importTableCellfrom"@mui/material/TableCell";
56
importTableContainerfrom"@mui/material/TableContainer";
67
importTableRowfrom"@mui/material/TableRow";
78
importTextFieldfrom"@mui/material/TextField";
8-
import{useFormik}from"formik";
9-
importtype{FC}from"react";
9+
import{typeFormikValues,useFormik}from"formik";
10+
import{typeChangeEvent,useState,typeFC,useEffect}from"react";
1011
import{useNavigate}from"react-router-dom";
1112
import*asYupfrom"yup";
1213
import{isApiValidationError}from"api/errors";
1314
import{RBACResourceActions}from"api/rbacresources_gen";
14-
importtype{Role}from"api/typesGenerated";
15+
importtype{
16+
Role,
17+
Permission,
18+
AssignableRoles,
19+
RBACResource,
20+
RBACAction,
21+
}from"api/typesGenerated";
1522
import{ErrorAlert}from"components/Alert/ErrorAlert";
1623
import{
1724
FormFields,
@@ -27,24 +34,29 @@ const validationSchema = Yup.object({
2734
});
2835

2936
exporttypeCreateEditRolePageViewProps={
37+
role:AssignableRoles|undefined;
38+
organization:string;
3039
onSubmit:(data:Role)=>void;
3140
error?:unknown;
3241
isLoading:boolean;
3342
};
3443

3544
exportconstCreateEditRolePageView:FC<CreateEditRolePageViewProps>=({
45+
role,
46+
organization,
3647
onSubmit,
3748
error,
3849
isLoading,
3950
})=>{
4051
constnavigate=useNavigate();
4152
constform=useFormik<Role>({
4253
initialValues:{
43-
name:"",
44-
display_name:"",
45-
site_permissions:[],
46-
organization_permissions:[],
47-
user_permissions:[],
54+
name:role?.name||"",
55+
organization_id:role?.organization_id||organization,
56+
display_name:role?.display_name||"",
57+
site_permissions:role?.site_permissions||[],
58+
organization_permissions:role?.organization_permissions||[],
59+
user_permissions:role?.user_permissions||[],
4860
},
4961
validationSchema,
5062
onSubmit,
@@ -55,12 +67,14 @@ export const CreateEditRolePageView: FC<CreateEditRolePageViewProps> = ({
5567
return(
5668
<>
5769
<PageHeadercss={{paddingTop:8}}>
58-
<PageHeaderTitle>Create custom role</PageHeaderTitle>
70+
<PageHeaderTitle>
71+
{role ?"Edit" :"Create"} custom role
72+
</PageHeaderTitle>
5973
</PageHeader>
6074
<HorizontalFormonSubmit={form.handleSubmit}>
6175
<FormSection
6276
title="Role settings"
63-
description="Set a name for this role."
77+
description="Set a nameand permissionsfor this role."
6478
>
6579
<FormFields>
6680
{Boolean(error)&&!isApiValidationError(error)&&(
@@ -80,7 +94,10 @@ export const CreateEditRolePageView: FC<CreateEditRolePageViewProps> = ({
8094
fullWidth
8195
label="Display Name"
8296
/>
83-
<ActionCheckboxespermissions={[]}></ActionCheckboxes>
97+
<ActionCheckboxes
98+
permissions={role?.organization_permissions||[]}
99+
form={form}
100+
/>
84101
</FormFields>
85102
</FormSection>
86103
<FormFooteronCancel={onCancel}isLoading={isLoading}/>
@@ -90,26 +107,69 @@ export const CreateEditRolePageView: FC<CreateEditRolePageViewProps> = ({
90107
};
91108

92109
interfaceActionCheckboxesProps{
93-
permissions:Permissions[];
110+
permissions:readonlyPermission[]|undefined;
111+
form:ReturnType<typeofuseFormik<Role>>&{values:Role};
94112
}
95113

96-
constActionCheckboxes:FC<ActionCheckboxesProps>=({ permissions})=>{
114+
constActionCheckboxes:FC<ActionCheckboxesProps>=({ permissions, form})=>{
115+
const[checkedActions,setIsChecked]=useState(permissions);
116+
117+
consthandleCheckChange=async(
118+
e:ChangeEvent<HTMLInputElement>,
119+
form:ReturnType<typeofuseFormik<Role>>&{values:Role},
120+
)=>{
121+
const{ name, checked}=e.currentTarget;
122+
const[resource_type,action]=name.split(":");
123+
124+
constnewPermissions=checked
125+
?[
126+
...(checkedActions??[]),
127+
{
128+
negate:false,
129+
resource_type:resource_typeasRBACResource,
130+
action:actionasRBACAction,
131+
},
132+
]
133+
:checkedActions?.filter(
134+
(p)=>p.resource_type!==resource_type||p.action!==action,
135+
);
136+
137+
setIsChecked(newPermissions);
138+
awaitform.setFieldValue("organization_permissions",checkedActions);
139+
};
140+
141+
// useEffect(() => {
142+
// setIsChecked(permissions);
143+
// }, [permissions]);
144+
97145
return(
98146
<TableContainer>
99147
<Table>
100148
<TableBody>
101-
{Object.entries(RBACResourceActions).map(([key,value])=>{
149+
{Object.entries(RBACResourceActions).map(([resourceKey,value])=>{
102150
return(
103-
<TableRowkey={key}>
151+
<TableRowkey={resourceKey}>
104152
<TableCell>
105-
<likey={key}css={styles.checkBoxes}>
106-
<inputtype="checkbox"/>{key}
153+
<likey={resourceKey}css={styles.checkBoxes}>
154+
{resourceKey}
107155
<ulcss={styles.checkBoxes}>
108-
{Object.entries(value).map(([key,value])=>{
156+
{Object.entries(value).map(([actionKey,value])=>{
109157
return(
110-
<likey={key}>
158+
<likey={actionKey}>
111159
<spancss={styles.actionText}>
112-
<inputtype="checkbox"/>{key}
160+
<Checkbox
161+
name={`${resourceKey}:${actionKey}`}
162+
checked={
163+
checkedActions?.some(
164+
(p)=>
165+
p.resource_type===resourceKey&&
166+
(p.action.toString()==="*"||
167+
p.action===actionKey),
168+
)||false
169+
}
170+
onChange={(e)=>handleCheckChange(e,form)}
171+
/>
172+
{actionKey}
113173
</span>{" "}
114174
-{" "}
115175
<spancss={styles.actionDescription}>{value}</span>
@@ -129,9 +189,6 @@ const ActionCheckboxes: FC<ActionCheckboxesProps> = ({ permissions }) => {
129189
};
130190

131191
conststyles={
132-
rolesDropdown:{
133-
marginBottom:20,
134-
},
135192
checkBoxes:{
136193
margin:0,
137194
listStyleType:"none",

‎site/src/pages/ManagementSettingsPage/CustomRolesPage/CustomRolesPageView.tsx

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
importtype{Interpolation,Theme}from"@emotion/react";
22
importAddOutlinedfrom"@mui/icons-material/AddOutlined";
33
importKeyboardArrowRightfrom"@mui/icons-material/KeyboardArrowRight";
4-
import{LoadingButton}from"@mui/lab";
5-
import{createFilterOptions}from"@mui/material/Autocomplete";
64
importButtonfrom"@mui/material/Button";
75
importSkeletonfrom"@mui/material/Skeleton";
86
importTablefrom"@mui/material/Table";
@@ -11,19 +9,17 @@ import TableCell from "@mui/material/TableCell";
119
importTableContainerfrom"@mui/material/TableContainer";
1210
importTableHeadfrom"@mui/material/TableHead";
1311
importTableRowfrom"@mui/material/TableRow";
14-
import{useState,typeFC}from"react";
12+
importtype{FC}from"react";
1513
import{LinkasRouterLink,useNavigate}from"react-router-dom";
1614
importtype{Role}from"api/typesGenerated";
1715
import{ChooseOne,Cond}from"components/Conditionals/ChooseOne";
1816
import{EmptyState}from"components/EmptyState/EmptyState";
1917
import{Paywall}from"components/Paywall/Paywall";
20-
import{Stack}from"components/Stack/Stack";
2118
import{
2219
TableLoader,
2320
TableLoaderSkeleton,
2421
TableRowSkeleton,
2522
}from"components/TableLoader/TableLoader";
26-
import{permissionsToCheck}from"contexts/auth/permissions";
2723
import{useClickableTableRow}from"hooks";
2824
import{docs}from"utils/docs";
2925

@@ -33,17 +29,14 @@ export type CustomRolesPageViewProps = {
3329
isCustomRolesEnabled:boolean;
3430
};
3531

36-
// const filter = createFilterOptions<Role>();
37-
3832
exportconstCustomRolesPageView:FC<CustomRolesPageViewProps>=({
3933
roles,
4034
canAssignOrgRole,
4135
isCustomRolesEnabled,
4236
})=>{
4337
constisLoading=Boolean(roles===undefined);
4438
constisEmpty=Boolean(roles&&roles.length===0);
45-
// const [selectedRole, setSelectedRole] = useState<Role | null>(null);
46-
console.log({ roles});
39+
4740
return(
4841
<>
4942
<ChooseOne>
@@ -59,9 +52,8 @@ export const CustomRolesPageView: FC<CustomRolesPageViewProps> = ({
5952
<Table>
6053
<TableHead>
6154
<TableRow>
62-
<TableCellwidth="33%">Name</TableCell>
63-
<TableCellwidth="33%">Display Name</TableCell>
64-
<TableCellwidth="33%">Permissions</TableCell>
55+
<TableCellwidth="50%">Name</TableCell>
56+
<TableCellwidth="49%">Permissions</TableCell>
6557
<TableCellwidth="1%"></TableCell>
6658
</TableRow>
6759
</TableHead>
@@ -125,9 +117,7 @@ const RoleRow: FC<RoleRowProps> = ({ role }) => {
125117

126118
return(
127119
<TableRowdata-testid={`role-${role.name}`}{...rowProps}>
128-
<TableCell>{role.name}</TableCell>
129-
130-
<TableCellcss={styles.secondary}>{role.display_name}</TableCell>
120+
<TableCell>{role.display_name||role.name}</TableCell>
131121

132122
<TableCellcss={styles.secondary}>
133123
{role.organization_permissions.length}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp