"use client"; import { useState, useRef, useEffect, useCallback } from "react"; import type { ColumnDef } from "@planarchy/shared"; interface ColumnTogglePanelProps { allColumns: ColumnDef[]; visibleKeys: string[]; onSetVisible: (keys: string[]) => void; defaultKeys: string[]; } export function ColumnTogglePanel({ allColumns, visibleKeys, onSetVisible, defaultKeys, }: ColumnTogglePanelProps) { const [open, setOpen] = useState(false); const panelRef = useRef(null); useEffect(() => { if (!open) return; function handleClick(e: MouseEvent) { if (panelRef.current && !panelRef.current.contains(e.target as Node)) { setOpen(false); } } document.addEventListener("mousedown", handleClick); return () => document.removeEventListener("mousedown", handleClick); }, [open]); const dragKey = useRef(null); function toggle(key: string) { const col = allColumns.find((c) => c.key === key); if (!col?.hideable) return; // always-visible columns can't be toggled const next = visibleKeys.includes(key) ? visibleKeys.filter((k) => k !== key) : [...visibleKeys, key]; onSetVisible(next); } function reset() { onSetVisible(defaultKeys); } const reorder = useCallback((fromKey: string, toKey: string) => { if (fromKey === toKey) return; const next = [...visibleKeys]; const from = next.indexOf(fromKey); const to = next.indexOf(toKey); if (from === -1 || to === -1) return; next.splice(from, 1); next.splice(to, 0, fromKey); onSetVisible(next); }, [visibleKeys, onSetVisible]); const builtins = allColumns.filter((c) => !c.isCustom); const customs = allColumns.filter((c) => c.isCustom); return (
{open && (
Columns
{builtins.map((col) => { const isVisible = visibleKeys.includes(col.key); return (
{ dragKey.current = col.key; }} onDragOver={(e) => { e.preventDefault(); }} onDrop={() => { if (dragKey.current) reorder(dragKey.current, col.key); dragKey.current = null; }} className={`flex items-center gap-2 px-3 py-1.5 hover:bg-gray-50 ${ !col.hideable ? "opacity-50" : "cursor-grab" }`} > {col.hideable && isVisible && ( )}
); })} {customs.length > 0 && ( <>

Custom Fields

{customs.map((col) => { const isVisible = visibleKeys.includes(col.key); return (
{ dragKey.current = col.key; }} onDragOver={(e) => { e.preventDefault(); }} onDrop={() => { if (dragKey.current) reorder(dragKey.current, col.key); dragKey.current = null; }} className="flex items-center gap-2 px-3 py-1.5 hover:bg-gray-50 cursor-grab" > {isVisible && }
); })} )}
)}
); }