Home / Function/ LeaveTeamButton() — supabase Function Reference

LeaveTeamButton() — supabase Function Reference

Architecture documentation for the LeaveTeamButton() function in LeaveTeamButton.tsx from the supabase codebase.

Entity Profile

Dependency Diagram

graph TD
  61f92e40_728b_d67b_5448_117bdf7ffa38["LeaveTeamButton()"]
  121b2c9f_7a78_911d_02ac_edca40a2af8a["hasMultipleOwners()"]
  61f92e40_728b_d67b_5448_117bdf7ffa38 -->|calls| 121b2c9f_7a78_911d_02ac_edca40a2af8a
  style 61f92e40_728b_d67b_5448_117bdf7ffa38 fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

apps/studio/components/interfaces/Organization/TeamSettings/LeaveTeamButton.tsx lines 18–142

export const LeaveTeamButton = () => {
  const router = useRouter()
  const { slug } = useParams()
  const { profile } = useProfile()
  const { data: selectedOrganization } = useSelectedOrganizationQuery()

  // if organizationMembersDeletionEnabled is false, you also can't delete yourself
  const { organizationMembersDelete: organizationMembersDeletionEnabled } = useIsFeatureEnabled([
    'organization_members:delete',
  ])

  const [isLeaving, setIsLeaving] = useState(false)
  const [isLeaveTeamModalOpen, setIsLeaveTeamModalOpen] = useState(false)
  const [_, setLastVisitedOrganization] = useLocalStorageQuery(
    LOCAL_STORAGE_KEYS.LAST_VISITED_ORGANIZATION,
    ''
  )

  const { refetch: refetchOrganizations } = useOrganizationsQuery()
  const { data: members } = useOrganizationMembersQuery({ slug })
  const { data: allRoles } = useOrganizationRolesV2Query({ slug })

  const roles = allRoles?.org_scoped_roles ?? []
  const currentUserMember = members?.find((member) => member.gotrue_id === profile?.gotrue_id)
  const currentUserRoleId = currentUserMember?.role_ids?.[0]
  const currentUserRole = roles.find((role) => role.id === currentUserRoleId)
  const isAdmin = currentUserRole?.name === 'Administrator'
  const isOwner = selectedOrganization?.is_owner

  const canLeave = !isOwner || (isOwner && hasMultipleOwners(members, roles))

  const { mutate: deleteMember } = useOrganizationMemberDeleteMutation({
    onSuccess: async () => {
      setIsLeaving(false)
      setIsLeaveTeamModalOpen(false)

      await refetchOrganizations()
      toast.success(`Successfully left ${selectedOrganization?.name}`)

      setLastVisitedOrganization('')
      router.push('/organizations')
    },
    onError: (error) => {
      setIsLeaving(false)
      toast.error(`Failed to leave organization: ${error?.message}`)
    },
  })

  const leaveTeam = async () => {
    if (!slug) return console.error('Org slug is required')
    if (!profile) return console.error('Profile is required')

    setIsLeaving(true)
    deleteMember({ slug, gotrueId: profile.gotrue_id })
  }

  return (
    <>
      <ButtonTooltip
        type="default"
        disabled={!canLeave || !organizationMembersDeletionEnabled || isLeaving}
        onClick={() => setIsLeaveTeamModalOpen(true)}
        tooltip={{
          content: {
            side: 'bottom',
            text: !canLeave
              ? 'An organization requires at least 1 owner'
              : !organizationMembersDeletionEnabled
                ? 'Unable to leave organization'
                : undefined,
          },
        }}
      >
        Leave team
      </ButtonTooltip>
      <ConfirmationModal
        size="medium"
        visible={isLeaveTeamModalOpen}
        title="Confirm to leave organization"
        confirmLabel="Leave"
        variant="warning"
        alert={{
          title: 'All of your user content will be permanently removed.',
          description: (
            <div>
              <p>
                Leaving the organization will delete all of your saved content in the projects of
                the organization, which includes:
              </p>
              <ul className="list-disc pl-4">
                <li>
                  SQL snippets <span className="text-foreground">(both private and shared)</span>
                </li>
                <li>Custom reports</li>
                <li>Log Explorer queries</li>
              </ul>
              {(isOwner || isAdmin) && (
                <div className="mt-2">
                  <p>
                    <span className="text-foreground">
                      Leaving won't remove your payment method or stop payments.
                    </span>
                  </p>
                  <ul className="list-disc pl-4">
                    <li>
                      The current payment method will remain active and may still be charged after
                      you leave.
                    </li>
                    <li>The billing address will remain unchanged.</li>
                  </ul>
                </div>
              )}
            </div>
          ),
        }}
        onCancel={() => setIsLeaveTeamModalOpen(false)}
        onConfirm={() => leaveTeam()}
      >
        <p className="text-sm text-foreground-light">
          Are you sure you want to leave this organization? This is permanent.
        </p>
      </ConfirmationModal>
    </>
  )
}

Subdomains

Frequently Asked Questions

What does LeaveTeamButton() do?
LeaveTeamButton() is a function in the supabase codebase.
What does LeaveTeamButton() call?
LeaveTeamButton() calls 1 function(s): hasMultipleOwners.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free