import { useEffect, useMemo, useState } from "react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { Database } from "lucide-react"; import { memoryApi } from "../api/memory"; import { useToast } from "../context/ToastContext"; import { queryKeys } from "../lib/queryKeys"; import { Button } from "@/components/ui/button"; function sourceLabel(source: string | null | undefined) { if (source === "project_override") return "Project override"; if (source === "company_default") return "Company default"; if (source === "agent_override") return "Agent override"; if (source === "binding_key") return "Direct binding key"; return "Unconfigured"; } export function ProjectMemorySettings({ companyId, projectId, }: { companyId: string; projectId: string; }) { const { pushToast } = useToast(); const queryClient = useQueryClient(); const [selectedBindingId, setSelectedBindingId] = useState("__inherit__"); const bindingsQuery = useQuery({ queryKey: queryKeys.memory.bindings(companyId), queryFn: () => memoryApi.listBindings(companyId), }); const resolvedBindingQuery = useQuery({ queryKey: queryKeys.memory.projectBinding(projectId), queryFn: () => memoryApi.getProjectBinding(projectId), }); useEffect(() => { const resolved = resolvedBindingQuery.data; if (!resolved) return; if (resolved.targetType === "project" && resolved.binding) { setSelectedBindingId(resolved.binding.id); return; } setSelectedBindingId("__inherit__"); }, [resolvedBindingQuery.data]); const currentSelection = useMemo(() => { const resolved = resolvedBindingQuery.data; if (!resolved) return "__inherit__"; if (resolved.targetType === "project" && resolved.binding) return resolved.binding.id; return "__inherit__"; }, [resolvedBindingQuery.data]); const saveOverride = useMutation({ mutationFn: () => memoryApi.setProjectBinding(projectId, selectedBindingId === "__inherit__" ? null : selectedBindingId), onSuccess: async () => { await queryClient.invalidateQueries({ queryKey: queryKeys.memory.all }); pushToast({ title: "Project memory binding updated", body: selectedBindingId === "__inherit__" ? "This project now inherits the company default binding." : "The project override is active for subsequent memory operations.", tone: "success", }); }, onError: (error) => { pushToast({ title: "Failed to update project memory binding", body: error instanceof Error ? error.message : "Unknown error", tone: "error", }); }, }); const loading = bindingsQuery.isLoading || resolvedBindingQuery.isLoading; const error = bindingsQuery.error ?? resolvedBindingQuery.error ?? null; const resolvedBinding = resolvedBindingQuery.data?.binding ?? null; return (
Loading memory state...
) : error ? ({error.message}
) : ( <>{resolvedBinding ? `${resolvedBinding.name ?? resolvedBinding.key} (${resolvedBinding.providerKey})` : "No memory binding resolves for this project yet."}
Source: {sourceLabel(resolvedBindingQuery.data?.source ?? null)}
> )}{saveOverride.error instanceof Error ? saveOverride.error.message : "Failed to update project memory binding"}
) : null}