- Add interactive ER diagram with ReactFlow + dagre auto-layout, accessible via right-click context menu on schema nodes in the sidebar - Enhance TableStructure: column comments, FK referenced table/columns, ON UPDATE/DELETE rules, new Triggers tab - Backend: rewrite get_table_constraints using pg_constraint for proper composite FK support, add get_table_triggers and get_schema_erd commands Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
55 lines
1.9 KiB
TypeScript
55 lines
1.9 KiB
TypeScript
import { memo } from "react";
|
|
import { Handle, Position, type NodeProps } from "@xyflow/react";
|
|
import type { ErdColumn } from "@/types";
|
|
import { KeyRound, Link } from "lucide-react";
|
|
|
|
export interface ErdTableNodeData {
|
|
label: string;
|
|
schema: string;
|
|
columns: ErdColumn[];
|
|
fkColumnNames: string[];
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
function ErdTableNodeComponent({ data }: NodeProps) {
|
|
const { label, columns, fkColumnNames } = data as unknown as ErdTableNodeData;
|
|
|
|
return (
|
|
<div className="min-w-[220px] rounded-lg border border-border bg-card text-card-foreground shadow-md">
|
|
<div className="rounded-t-lg border-b bg-primary/10 px-3 py-2 text-xs font-bold tracking-wide text-primary">
|
|
{label}
|
|
</div>
|
|
<div className="divide-y divide-border/50">
|
|
{(columns as ErdColumn[]).map((col, i) => (
|
|
<div key={i} className="flex items-center gap-1.5 px-3 py-1 text-[11px]">
|
|
{col.is_primary_key ? (
|
|
<KeyRound className="h-3 w-3 shrink-0 text-amber-500" />
|
|
) : (fkColumnNames as string[]).includes(col.name) ? (
|
|
<Link className="h-3 w-3 shrink-0 text-blue-400" />
|
|
) : (
|
|
<span className="h-3 w-3 shrink-0" />
|
|
)}
|
|
<span className="font-medium">{col.name}</span>
|
|
<span className="ml-auto text-muted-foreground">{col.data_type}</span>
|
|
{col.is_nullable && (
|
|
<span className="text-muted-foreground/60">?</span>
|
|
)}
|
|
</div>
|
|
))}
|
|
</div>
|
|
<Handle
|
|
type="target"
|
|
position={Position.Left}
|
|
className="!w-1.5 !h-1.5 !bg-primary !opacity-0 hover:!opacity-100 !border-none !min-w-0 !min-h-0"
|
|
/>
|
|
<Handle
|
|
type="source"
|
|
position={Position.Right}
|
|
className="!w-1.5 !h-1.5 !bg-primary !opacity-0 hover:!opacity-100 !border-none !min-w-0 !min-h-0"
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export const ErdTableNode = memo(ErdTableNodeComponent);
|