"use client"; import { useState } from "react"; import Link from "next/link"; import { useQuery } from "@tanstack/react-query"; import { Check, X } from "lucide-react"; import { Popover, PopoverTrigger, PopoverContent, Spinner } from "@/components/ui/primitives"; import { api } from "@/lib/client/api"; import { cn } from "@/lib/utils"; import type { Property, RelationRef } from "@/lib/databases/types"; export function RelationChip({ r, onRemove, className }: { r: RelationRef; onRemove?: () => void; className?: string }) { return e.stopPropagation()} className="truncate underline decoration-line underline-offset-2 hover:text-accent">{r.icon ? `${r.icon} ` : ""}{r.title || "Untitled"}{onRemove && { e.stopPropagation(); onRemove(); }} className="-mr-0.5 rounded p-0.5 text-fg-faint hover:text-fg">}; } export function RelationPopover({ p, value, onChange, open, onOpenChange, children }: { p: Property; value: unknown; onChange: (v: RelationRef[]) => void; open: boolean; onOpenChange: (o: boolean) => void; children: React.ReactNode }) { const [q, setQ] = useState(""); const sel = (Array.isArray(value) ? value : []) as RelationRef[]; const target = p.config.targetDatabaseId as string | undefined; const { data, isLoading } = useQuery({ queryKey: ["db-rel", target, q], enabled: open && !!target, queryFn: () => api(`/api/databases/${target}/rows?q=${encodeURIComponent(q)}&limit=50`) }); const toggle = (r: RelationRef) => { const has = sel.some((x) => x.rowId === r.rowId); if (p.config.single) { onChange(has ? [] : [r]); onOpenChange(false); } else onChange(has ? sel.filter((x) => x.rowId !== r.rowId) : [...sel, r]); }; return ( { onOpenChange(o); if (!o) setQ(""); }}>{children} { e.preventDefault(); (e.currentTarget as HTMLElement).querySelector("input")?.focus(); }}> {sel.length > 0 && {sel.map((r) => toggle(r)} />)}} {!target ? No target database configured. : <> setQ(e.target.value)} placeholder="Search rows…" className="h-8 w-full rounded-md bg-bg-sunk px-2 text-[13px] outline-none" onKeyDown={(e) => { if (e.key === "Escape") onOpenChange(false); if (e.key === "Enter" && data?.length === 1) toggle(data[0]); }} /> {isLoading ? : (data ?? []).map((r) => toggle(r)} className="flex h-9 w-full items-center gap-2 rounded-md px-2 text-left text-[13px] hover:bg-bg-sunk">{r.icon ?? "📄"}{r.title || "Untitled"}{sel.some((x) => x.rowId === r.rowId) && })}{data && !data.length && No matching rows.} >} ); }