AddUserDropdown.tsx 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import { PermissionAction } from '@supabase/shared-types/out/constants'
  2. import { ChevronDown, Mail, UserPlus } from 'lucide-react'
  3. import { parseAsBoolean, useQueryState } from 'nuqs'
  4. import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuTrigger } from 'ui'
  5. import CreateUserModal from './CreateUserModal'
  6. import InviteUserModal from './InviteUserModal'
  7. import { DropdownMenuItemTooltip } from '@/components/ui/DropdownMenuItemTooltip'
  8. import { ShortcutBadge } from '@/components/ui/ShortcutBadge'
  9. import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
  10. import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
  11. import { SHORTCUT_IDS } from '@/state/shortcuts/registry'
  12. export const AddUserDropdown = () => {
  13. const showSendInvitation = useIsFeatureEnabled('authentication:show_send_invitation')
  14. const { can: canInviteUsers } = useAsyncCheckPermissions(
  15. PermissionAction.AUTH_EXECUTE,
  16. 'invite_user'
  17. )
  18. const { can: canCreateUsers } = useAsyncCheckPermissions(
  19. PermissionAction.AUTH_EXECUTE,
  20. 'create_user'
  21. )
  22. const [inviteVisible, setInviteVisible] = useQueryState(
  23. 'invite',
  24. parseAsBoolean.withDefault(false).withOptions({ history: 'push', clearOnDefault: true })
  25. )
  26. const [createVisible, setCreateVisible] = useQueryState(
  27. 'new',
  28. parseAsBoolean.withDefault(false).withOptions({ history: 'push', clearOnDefault: true })
  29. )
  30. return (
  31. <>
  32. <DropdownMenu>
  33. <DropdownMenuTrigger asChild>
  34. <Button type="primary" iconRight={<ChevronDown size={14} strokeWidth={1.5} />}>
  35. Add user
  36. </Button>
  37. </DropdownMenuTrigger>
  38. <DropdownMenuContent side="bottom" align="end" className="w-52">
  39. {showSendInvitation && (
  40. <DropdownMenuItemTooltip
  41. className="gap-x-2"
  42. disabled={!canInviteUsers}
  43. onClick={() => {
  44. if (canInviteUsers) setInviteVisible(true)
  45. }}
  46. tooltip={{
  47. content: { side: 'left', text: 'You need additional permissions to invite users' },
  48. }}
  49. >
  50. <Mail size={14} className="shrink-0" />
  51. <p className="flex-1 min-w-0">Send invitation</p>
  52. {canInviteUsers && (
  53. <ShortcutBadge
  54. shortcutId={SHORTCUT_IDS.AUTH_USERS_INVITE_USER}
  55. className="shrink-0"
  56. />
  57. )}
  58. </DropdownMenuItemTooltip>
  59. )}
  60. <DropdownMenuItemTooltip
  61. className="gap-x-2 pointer-events-auto!"
  62. disabled={!canCreateUsers}
  63. onClick={() => {
  64. if (canCreateUsers) setCreateVisible(true)
  65. }}
  66. tooltip={{
  67. content: { side: 'left', text: 'You need additional permissions to create users' },
  68. }}
  69. >
  70. <UserPlus size={14} className="shrink-0" />
  71. <p className="flex-1 min-w-0">Create new user</p>
  72. {canCreateUsers && (
  73. <ShortcutBadge
  74. shortcutId={SHORTCUT_IDS.AUTH_USERS_CREATE_USER}
  75. className="shrink-0"
  76. />
  77. )}
  78. </DropdownMenuItemTooltip>
  79. </DropdownMenuContent>
  80. </DropdownMenu>
  81. <InviteUserModal visible={inviteVisible} setVisible={setInviteVisible} />
  82. <CreateUserModal visible={createVisible} setVisible={setCreateVisible} />
  83. </>
  84. )
  85. }