import { useEffect, useRef, useState } from 'react' // The pivot layout, as one control rather than a row of equal chips. // // Two lists, because a layout is one of two different things: Published, which // everyone on this forecast sees and only its owner or an admin may change, and // Mine, which nobody else lists. Everything you cannot write is still there to // apply -- it is only the write controls that are withheld, so a click never // answers 403. export default function LayoutMenu({ layouts = [], activeLayoutId, dirty, onApply, onSave, onSaveAs, onSetVisibility, onSetDefault, onRename, onDelete, onReset }) { const [open, setOpen] = useState(false) const [saveName, setSaveName] = useState('') const [savePublic, setSavePublic] = useState(false) const [renaming, setRenaming] = useState(null) const [renameTo, setRenameTo] = useState('') const boxRef = useRef(null) // Close on an outside click or Escape. Capture phase: the pivot lives in a // shadow root and retargets its events, so a bubbled listener on document // sees the host rather than the real target and cannot tell inside from out. useEffect(() => { if (!open) return const onDown = (e) => { if (!boxRef.current?.contains(e.target)) setOpen(false) } const onKey = (e) => { if (e.key === 'Escape') setOpen(false) } document.addEventListener('mousedown', onDown, true) window.addEventListener('keydown', onKey) return () => { document.removeEventListener('mousedown', onDown, true) window.removeEventListener('keydown', onKey) } }, [open]) const active = layouts.find(l => l.id === activeLayoutId) const published = layouts.filter(l => l.visibility === 'published') const mine = layouts.filter(l => l.visibility === 'private') const submitSaveAs = () => { const name = saveName.trim() if (!name) return onSaveAs(name, savePublic ? 'published' : 'private') setSaveName('') setOpen(false) } const submitRename = (l) => { const name = renameTo.trim() if (name && name !== l.name) onRename(l, name) setRenaming(null) } const iconBtn = 'px-1 rounded text-gray-400 hover:text-gray-700 hover:bg-gray-100 leading-none' const row = (l) => (