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

Commite6cd300

Browse files
authored
feat: add warning dialog when removing member from organization (#14695)
resolves#14705 <img width="684" alt="Screenshot 2024-09-27 at 4 34 02 PM"src="https://github.com/user-attachments/assets/5c3b6c3e-2afc-4405-8bed-d9ea80607411">
1 parentb805509 commite6cd300

File tree

4 files changed

+100
-53
lines changed

4 files changed

+100
-53
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ export const CustomRolesPage: FC = () => {
8787
onCancel={()=>setRoleToDelete(undefined)}
8888
onConfirm={async()=>{
8989
try{
90-
awaitdeleteRoleMutation.mutateAsync(roleToDelete!.name);
90+
if(roleToDelete){
91+
awaitdeleteRoleMutation.mutateAsync(roleToDelete.name);
92+
}
9193
setRoleToDelete(undefined);
9294
awaitorganizationRolesQuery.refetch();
9395
displaySuccess("Custom role deleted successfully!");

‎site/src/pages/ManagementSettingsPage/OrganizationMembersPage.test.tsx‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ const removeMember = async () => {
5050

5151
constremoveButton=screen.getByText(/Remove/);
5252
awaituser.click(removeButton);
53+
54+
constdialog=awaitwithin(document.body).findByRole("dialog");
55+
awaituser.click(within(dialog).getByRole("button",{name:"Remove"}));
5356
};
5457

5558
constupdateUserRole=async(role:SlimRole)=>{
@@ -80,7 +83,7 @@ describe("OrganizationMembersPage", () => {
8083
it("shows a success message",async()=>{
8184
awaitrenderPage();
8285
awaitremoveMember();
83-
awaitscreen.findByText("Member removed successfully.");
86+
awaitscreen.findByText("User removedfrom organizationsuccessfully!");
8487
});
8588
});
8689
});
Lines changed: 91 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import{
2-
groupsByUserId,
3-
groupsByUserIdInOrganization,
4-
}from"api/queries/groups";
1+
importtype{Interpolation,Theme}from"@emotion/react";
2+
import{getErrorMessage}from"api/errors";
3+
import{groupsByUserIdInOrganization}from"api/queries/groups";
54
import{
65
addOrganizationMember,
76
organizationMembers,
@@ -11,9 +10,12 @@ import {
1110
}from"api/queries/organizations";
1211
import{organizationRoles}from"api/queries/roles";
1312
importtype{OrganizationMemberWithUserData,User}from"api/typesGenerated";
13+
import{ConfirmDialog}from"components/Dialogs/ConfirmDialog/ConfirmDialog";
14+
import{displayError,displaySuccess}from"components/GlobalSnackbar/utils";
1415
import{Loader}from"components/Loader/Loader";
16+
import{Stack}from"components/Stack/Stack";
1517
import{useAuthenticated}from"contexts/auth/RequireAuth";
16-
importtype{FC}from"react";
18+
import{typeFC,useState}from"react";
1719
import{useMutation,useQuery,useQueryClient}from"react-query";
1820
import{useParams}from"react-router-dom";
1921
import{useOrganizationSettings}from"./ManagementSettingsLayout";
@@ -52,45 +54,97 @@ const OrganizationMembersPage: FC = () => {
5254
constorganization=organizations?.find((o)=>o.name===organizationName);
5355
constpermissionsQuery=useQuery(organizationPermissions(organization?.id));
5456

57+
const[memberToDelete,setMemberToDelete]=
58+
useState<OrganizationMemberWithUserData>();
59+
5560
constpermissions=permissionsQuery.data;
5661
if(!permissions){
5762
return<Loader/>;
5863
}
5964

6065
return(
61-
<OrganizationMembersPageView
62-
allAvailableRoles={organizationRolesQuery.data}
63-
canEditMembers={permissions.editMembers}
64-
error={
65-
membersQuery.error??
66-
addMemberMutation.error??
67-
removeMemberMutation.error??
68-
updateMemberRolesMutation.error
69-
}
70-
isAddingMember={addMemberMutation.isLoading}
71-
isUpdatingMemberRoles={updateMemberRolesMutation.isLoading}
72-
me={me}
73-
members={members}
74-
groupsByUserId={groupsByUserIdQuery.data}
75-
addMember={async(user:User)=>{
76-
awaitaddMemberMutation.mutateAsync(user.id);
77-
voidmembersQuery.refetch();
78-
}}
79-
removeMember={async(member:OrganizationMemberWithUserData)=>{
80-
awaitremoveMemberMutation.mutateAsync(member.user_id);
81-
voidmembersQuery.refetch();
82-
}}
83-
updateMemberRoles={async(
84-
member:OrganizationMemberWithUserData,
85-
newRoles:string[],
86-
)=>{
87-
awaitupdateMemberRolesMutation.mutateAsync({
88-
userId:member.user_id,
89-
roles:newRoles,
90-
});
91-
}}
92-
/>
66+
<>
67+
<OrganizationMembersPageView
68+
allAvailableRoles={organizationRolesQuery.data}
69+
canEditMembers={permissions.editMembers}
70+
error={
71+
membersQuery.error??
72+
addMemberMutation.error??
73+
removeMemberMutation.error??
74+
updateMemberRolesMutation.error
75+
}
76+
isAddingMember={addMemberMutation.isLoading}
77+
isUpdatingMemberRoles={updateMemberRolesMutation.isLoading}
78+
me={me}
79+
members={members}
80+
groupsByUserId={groupsByUserIdQuery.data}
81+
addMember={async(user:User)=>{
82+
awaitaddMemberMutation.mutateAsync(user.id);
83+
voidmembersQuery.refetch();
84+
}}
85+
removeMember={setMemberToDelete}
86+
updateMemberRoles={async(
87+
member:OrganizationMemberWithUserData,
88+
newRoles:string[],
89+
)=>{
90+
awaitupdateMemberRolesMutation.mutateAsync({
91+
userId:member.user_id,
92+
roles:newRoles,
93+
});
94+
}}
95+
/>
96+
97+
<ConfirmDialog
98+
type="delete"
99+
open={memberToDelete!==undefined}
100+
onClose={()=>setMemberToDelete(undefined)}
101+
title="Remove member"
102+
confirmText="Remove"
103+
onConfirm={async()=>{
104+
try{
105+
if(memberToDelete){
106+
awaitremoveMemberMutation.mutateAsync(memberToDelete?.user_id);
107+
}
108+
setMemberToDelete(undefined);
109+
awaitmembersQuery.refetch();
110+
displaySuccess("User removed from organization successfully!");
111+
}catch(error){
112+
setMemberToDelete(undefined);
113+
displayError(
114+
getErrorMessage(error,"Failed to remove user from organization"),
115+
);
116+
}finally{
117+
setMemberToDelete(undefined);
118+
}
119+
}}
120+
description={
121+
<Stack>
122+
<p>
123+
Removing this member will:
124+
<ul>
125+
<li>Remove the member from all groups in this organization</li>
126+
<li>Remove all user role assignments</li>
127+
<li>
128+
Orphan all the member's workspaces associated with this
129+
organization
130+
</li>
131+
</ul>
132+
</p>
133+
134+
<pcss={styles.test}>
135+
Are you sure you want to remove this member?
136+
</p>
137+
</Stack>
138+
}
139+
/>
140+
</>
93141
);
94142
};
95143

144+
conststyles={
145+
test:{
146+
paddingBottom:20,
147+
},
148+
}satisfiesRecord<string,Interpolation<Theme>>;
149+
96150
exportdefaultOrganizationMembersPage;

‎site/src/pages/ManagementSettingsPage/OrganizationMembersPageView.tsx‎

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ interface OrganizationMembersPageViewProps {
4444
members:Array<OrganizationMemberTableEntry>|undefined;
4545
groupsByUserId:GroupsByUserId|undefined;
4646
addMember:(user:User)=>Promise<void>;
47-
removeMember:(member:OrganizationMemberWithUserData)=>Promise<void>;
47+
removeMember:(member:OrganizationMemberWithUserData)=>void;
4848
updateMemberRoles:(
4949
member:OrganizationMemberWithUserData,
5050
newRoles:string[],
@@ -134,19 +134,7 @@ export const OrganizationMembersPageView: FC<
134134
<MoreMenuContent>
135135
<MoreMenuItem
136136
danger
137-
onClick={async()=>{
138-
try{
139-
awaitprops.removeMember(member);
140-
displaySuccess("Member removed successfully.");
141-
}catch(error){
142-
displayError(
143-
getErrorMessage(
144-
error,
145-
"Failed to remove member.",
146-
),
147-
);
148-
}
149-
}}
137+
onClick={()=>props.removeMember(member)}
150138
>
151139
Remove
152140
</MoreMenuItem>

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp