import { useEffect, useMemo, useState } from 'react'; import { zodResolver } from '@hookform/resolvers/zod'; import { Trans, useLingui } from '@lingui/react/macro'; import { TeamMemberRole } from '@prisma/client'; import type * as DialogPrimitive from '@radix-ui/react-dialog'; import { InfoIcon } from 'lucide-react'; import { useForm } from 'react-hook-form'; import { Link } from 'react-router'; import { match } from 'ts-pattern'; import { z } from 'zod'; import { TEAM_MEMBER_ROLE_HIERARCHY } from '@documenso/lib/constants/teams'; import { TEAM_MEMBER_ROLE_MAP } from '@documenso/lib/constants/teams-translations'; import { trpc } from '@documenso/trpc/react'; import { Button } from '@documenso/ui/primitives/button'; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from '@documenso/ui/primitives/dialog'; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from '@documenso/ui/primitives/form/form'; import { Input } from '@documenso/ui/primitives/input'; import { MultiSelectCombobox } from '@documenso/ui/primitives/multi-select-combobox'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@documenso/ui/primitives/select'; import { Tooltip, TooltipContent, TooltipTrigger } from '@documenso/ui/primitives/tooltip'; import { useToast } from '@documenso/ui/primitives/use-toast'; import { useCurrentTeam } from '~/providers/team'; export type TeamMemberCreateDialogProps = { trigger?: React.ReactNode; } & Omit; const ZAddTeamMembersFormSchema = z.object({ members: z.array( z.object({ organisationMemberId: z.string(), teamRole: z.nativeEnum(TeamMemberRole), }), ), }); type TAddTeamMembersFormSchema = z.infer; export const TeamMemberCreateDialog = ({ trigger, ...props }: TeamMemberCreateDialogProps) => { const [open, setOpen] = useState(false); const [step, setStep] = useState<'SELECT' | 'MEMBERS'>('SELECT'); const { t } = useLingui(); const { toast } = useToast(); const team = useCurrentTeam(); const form = useForm({ resolver: zodResolver(ZAddTeamMembersFormSchema), defaultValues: { members: [], }, }); const { mutateAsync: createTeamMembers } = trpc.team.member.createMany.useMutation(); const organisationMemberQuery = trpc.organisation.member.find.useQuery({ organisationId: team.organisationId, }); const teamMemberQuery = trpc.team.member.find.useQuery({ teamId: team.id, }); const avaliableOrganisationMembers = useMemo(() => { const organisationMembers = organisationMemberQuery.data?.data ?? []; const teamMembers = teamMemberQuery.data?.data ?? []; return organisationMembers.filter( (member) => !teamMembers.some((teamMember) => teamMember.id === member.id), ); }, [organisationMemberQuery, teamMemberQuery]); const onFormSubmit = async ({ members }: TAddTeamMembersFormSchema) => { try { await createTeamMembers({ teamId: team.id, organisationMembers: members, }); toast({ title: t`Success`, description: t`Team members have been added.`, duration: 5000, }); setOpen(false); } catch { toast({ title: t`An unknown error occurred`, description: t`We encountered an unknown error while attempting to add team members. Please try again later.`, variant: 'destructive', }); } }; useEffect(() => { if (!open) { form.reset(); setStep('SELECT'); } }, [open, form]); return ( e.stopPropagation()} asChild> {match(step) .with('SELECT', () => ( Add members To be able to add members to a team, you must first add them to the organisation. For more information, please see the{' '} documentation . Select members or groups of members to add to the team. )) .with('MEMBERS', () => ( Add members roles Configure the team roles for each member )) .exhaustive()}
{step === 'SELECT' && ( <> ( Members ({ label: member.name, value: member.id, }))} loading={organisationMemberQuery.isLoading} selectedValues={field.value.map( (member) => member.organisationMemberId, )} onChange={(value) => { field.onChange( value.map((organisationMemberId) => ({ organisationMemberId, teamRole: field.value.find( (member) => member.organisationMemberId === organisationMemberId, )?.teamRole || TeamMemberRole.MEMBER, })), ); }} className="bg-background w-full" emptySelectionPlaceholder={t`Select members`} /> Select members to add to this team )} /> )} {step === 'MEMBERS' && ( <>
{form.getValues('members').map((member, index) => (
{index === 0 && ( Member )} id === member.organisationMemberId, )?.name || '' } />
( {index === 0 && ( Team Role )} )} />
))}
)}
); };