import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import type { Agent } from "@paperclipai/shared"; import { toolsApi } from "@/api/tools"; import { queryKeys } from "@/lib/queryKeys"; import { AgentMultiSelect } from "@/components/AgentMultiSelect"; import { RadioCardGroup } from "@/components/ui/radio-card"; export function EmailConnectionAccess({ companyId, connectionId, agents, }: { companyId: string; connectionId: string; agents: Agent[]; }) { const cache = useQueryClient(); const grants = useQuery({ queryKey: queryKeys.tools.connectionGrants(connectionId), queryFn: () => toolsApi.listConnectionGrants(connectionId), }); const installs = useQuery({ queryKey: queryKeys.tools.connectionInstalls(connectionId), queryFn: () => toolsApi.getConnectionInstalls(connectionId), }); const save = useMutation({ mutationFn: ( next: Array<{ targetType: "company" | "agent"; targetId: string }>, ) => toolsApi.putConnectionInstalls(connectionId, next), onSuccess: () => { void cache.invalidateQueries({ queryKey: queryKeys.tools.connectionInstalls(connectionId), }); }, }); if (grants.isLoading || installs.isLoading) return

Loading access…

; if (grants.error || installs.error) return (

Connection access could not be loaded.

); const active = grants.data?.grants.filter((g) => g.status === "active") ?? []; const everyone = active.some((g) => g.kind === "organization"); const personal = active.find((g) => g.kind === "user"); const humanLabel = everyone ? "Any human in the organization" : personal ? personal.subjectUserId === grants.data?.currentUserId ? "Just me" : "Only the credential owner" : "Access revoked"; const allAgents = installs.data?.installs.some((i) => i.targetType === "company") ?? false; const selected = new Set( installs.data?.installs .filter((i) => i.targetType === "agent") .map((i) => i.targetId), ); const disabled = !grants.data?.capabilities.canConfigure || save.isPending; return (

Which humans can use this credential?

{humanLabel}

Which agents can use this connection?

save.mutate( value === "all" ? [{ targetType: "company", targetId: companyId }] : Array.from(selected, (targetId) => ({ targetType: "agent", targetId, })), ) } /> {!allAgents && ( a.status !== "terminated")} selectedAgentIds={selected} disabled={disabled} onSave={(ids) => save.mutate( Array.from(ids, (targetId) => ({ targetType: "agent", targetId, })), ) } /> )}

Removing an assigned agent stops receiving and sending from its inbox.

{save.error && (

{save.error.message}

)}
); }