Skip to content

Commit

Permalink
fix: remove organization owner from org (#5907)
Browse files Browse the repository at this point in the history
  • Loading branch information
n1ru4l authored Nov 13, 2024
1 parent 4fea8ba commit 5adfb6c
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 25 deletions.
5 changes: 5 additions & 0 deletions .changeset/tame-panthers-sleep.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'hive': patch
---

Remove option to remove the organization owner from the organization.
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,6 @@ export default gql`
"""
viewerCanAssignUserRoles: Boolean!
"""
Whether the viewer can remove a member from the organization
"""
viewerCanRemoveMember: Boolean!
"""
Whether the viewer can modify roles of members within the organization
"""
viewerCanManageRoles: Boolean!
Expand Down Expand Up @@ -326,6 +322,10 @@ export default gql`
canLeaveOrganization: Boolean!
role: MemberRole
isAdmin: Boolean!
"""
Whether the viewer can remove this member from the organization.
"""
viewerCanRemove: Boolean!
}
type MemberRole {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { MemberResolvers } from './../../../__generated__/types';

export const Member: Pick<
MemberResolvers,
'canLeaveOrganization' | 'isAdmin' | 'role' | '__isTypeOf'
'canLeaveOrganization' | 'isAdmin' | 'role' | 'viewerCanRemove' | '__isTypeOf'
> = {
canLeaveOrganization: async (member, _, { injector }) => {
const { result } = await injector.get(OrganizationManager).canLeaveOrganization({
Expand All @@ -16,4 +16,17 @@ export const Member: Pick<
isAdmin: (member, _, { injector }) => {
return member.isOwner || injector.get(OrganizationManager).isAdminRole(member.role);
},
viewerCanRemove: async (member, _arg, { session }) => {
if (member.isOwner) {
return false;
}

return await session.canPerformAction({
action: 'member:removeMember',
organizationId: member.organization,
params: {
organizationId: member.organization,
},
});
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ export const Organization: Pick<
| 'viewerCanManageRoles'
| 'viewerCanMigrateLegacyMemberRoles'
| 'viewerCanModifySlug'
| 'viewerCanRemoveMember'
| 'viewerCanSeeMembers'
| 'viewerCanTransferOwnership'
| '__isTypeOf'
Expand Down Expand Up @@ -212,15 +211,6 @@ export const Organization: Pick<
},
});
},
viewerCanRemoveMember: (organization, _arg, { session }) => {
return session.canPerformAction({
action: 'member:removeMember',
organizationId: organization.id,
params: {
organizationId: organization.id,
},
});
},
viewerCanManageRoles: (organization, _arg, { session }) => {
return session.canPerformAction({
action: 'member:modifyRole',
Expand Down
34 changes: 24 additions & 10 deletions packages/web/app/src/components/organization/members/list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,8 @@ const OrganizationMemberRow_MemberFragment = graphql(`
id
name
}
isOwner
viewerCanRemove
...ChangePermissionsModal_MemberFragment
...OrganizationMemberRoleSwitcher_MemberFragment
}
Expand Down Expand Up @@ -438,16 +439,30 @@ function OrganizationMemberRow(props: {
<h4 className="text-xs text-gray-400">{member.user.email}</h4>
</td>
<td className="relative py-3 text-center text-sm">
<OrganizationMemberRoleSwitcher
organization={organization}
memberId={member.id}
memberName={member.user.displayName}
memberRoleId={member.role?.id}
member={member}
/>
{member.isOwner ? (
<TooltipProvider>
<Tooltip>
<TooltipTrigger>
<span className="font-bold">Owner</span>
</TooltipTrigger>
<TooltipContent className="max-w-[200px] text-left">
The organization owner has full access to everything within the organization. The
role of the owner can not be changed.
</TooltipContent>
</Tooltip>
</TooltipProvider>
) : (
<OrganizationMemberRoleSwitcher
organization={organization}
memberId={member.id}
memberName={member.user.displayName}
memberRoleId={member.role?.id}
member={member}
/>
)}
</td>
<td className="py-3 text-right text-sm">
{organization.viewerCanRemoveMember && (
{member.viewerCanRemove && (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" className="data-[state=open]:bg-muted flex size-8 p-0">
Expand Down Expand Up @@ -491,7 +506,6 @@ const OrganizationMembers_OrganizationFragment = graphql(`
total
}
viewerCanManageInvitations
viewerCanRemoveMember
viewerCanMigrateLegacyMemberRoles
...OrganizationMemberRoleSwitcher_OrganizationFragment
...MemberInvitationForm_OrganizationFragment
Expand Down

0 comments on commit 5adfb6c

Please sign in to comment.