From 283334921b61a95acceb7dbb84f88d3d41bb9bb8 Mon Sep 17 00:00:00 2001 From: David Nguyen Date: Thu, 9 Apr 2026 14:32:29 +1000 Subject: [PATCH] fix: update team member invitation ux (#2687) --- .../dialogs/team-member-create-dialog.tsx | 101 +++++++++++------- 1 file changed, 61 insertions(+), 40 deletions(-) diff --git a/apps/remix/app/components/dialogs/team-member-create-dialog.tsx b/apps/remix/app/components/dialogs/team-member-create-dialog.tsx index b8e5cfef5..f9ccf3f5e 100644 --- a/apps/remix/app/components/dialogs/team-member-create-dialog.tsx +++ b/apps/remix/app/components/dialogs/team-member-create-dialog.tsx @@ -10,8 +10,10 @@ import { Link } from 'react-router'; import { match } from 'ts-pattern'; import { z } from 'zod'; +import { useCurrentOrganisation } from '@documenso/lib/client-only/providers/organisation'; import { TEAM_MEMBER_ROLE_HIERARCHY } from '@documenso/lib/constants/teams'; import { TEAM_MEMBER_ROLE_MAP } from '@documenso/lib/constants/teams-translations'; +import { canExecuteOrganisationAction } from '@documenso/lib/utils/organisations'; import { trpc } from '@documenso/trpc/react'; import { Alert, AlertDescription } from '@documenso/ui/primitives/alert'; import { Button } from '@documenso/ui/primitives/button'; @@ -73,8 +75,14 @@ export const TeamMemberCreateDialog = ({ trigger, ...props }: TeamMemberCreateDi const { toast } = useToast(); const team = useCurrentTeam(); + const organisation = useCurrentOrganisation(); const utils = trpc.useUtils(); + const canInviteOrganisationMembers = canExecuteOrganisationAction( + 'MANAGE_ORGANISATION', + organisation.currentOrganisationRole, + ); + const form = useForm({ resolver: zodResolver(ZAddTeamMembersFormSchema), defaultValues: { @@ -106,7 +114,7 @@ export const TeamMemberCreateDialog = ({ trigger, ...props }: TeamMemberCreateDi const onFormSubmit = async ({ members }: TAddTeamMembersFormSchema) => { if (members.length === 0) { - if (hasNoAvailableMembers) { + if (hasNoAvailableMembers && canInviteOrganisationMembers) { setInviteDialogOpen(true); return; } @@ -231,7 +239,7 @@ export const TeamMemberCreateDialog = ({ trigger, ...props }: TeamMemberCreateDi onKeyDown={(e) => { if (e.key === 'Enter' && form.getValues('members').length === 0) { e.preventDefault(); - if (hasNoAvailableMembers) { + if (hasNoAvailableMembers && canInviteOrganisationMembers) { setInviteDialogOpen(true); } // Don't show toast - the disabled Next button already communicates this @@ -260,21 +268,32 @@ export const TeamMemberCreateDialog = ({ trigger, ...props }: TeamMemberCreateDi No organisation members available

- - To add members to this team, you must first add them to the - organisation. - + {canInviteOrganisationMembers ? ( + + To add members to this team, you must first add them to the + organisation. + + ) : ( + + To add members to this team, they must first be invited to the + organisation. Only organisation admins and managers can invite + new members — please contact one of them to invite members on + your behalf. + + )}

- - - Invite organisation members - - } - /> + {canInviteOrganisationMembers && ( + + + Invite organisation members + + } + /> + )} ) : ( Select members to add to this team - -
- -
- - Can't find someone?{' '} - - Invite them to the organisation first - - } - /> - -
+ {canInviteOrganisationMembers && ( + +
+ +
+ + Can't find someone?{' '} + + Invite them to the organisation first + + } + /> + +
+ )} )}