import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import type { Agent } from "@paperclipai/shared";
import { describeError } from "@/api/errors";
import { toolsApi } from "@/api/tools";
import { QueryErrorState, useQueryView } from "@/components/QueryView";
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),
});
},
});
const grantsView = useQueryView(grants);
const installsView = useQueryView(installs);
const failedView = [grantsView, installsView].find((view) => view.kind === "error");
if (failedView)
return (
Loading access…
; 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 ({humanLabel}
Removing an assigned agent stops receiving and sending from its inbox.
{save.error && ({describeError(save.error).body}
)}