// Atoms reused across screens const Spark = ({ w = 60, h = 16, accent = false, seed = 1 }) => { const pts = []; let v = h * 0.5; for (let i = 0; i < 14; i++) { v += (Math.sin(seed * i * 1.7) + Math.cos(seed * i * 0.9)) * 2.5; v = Math.max(2, Math.min(h - 2, v)); pts.push(`${(i / 13) * (typeof w === 'number' ? w : 100)},${v.toFixed(1)}`); } return ( ); }; const ToolDot = ({ tool }) => ( ); const ToolTag = ({ tool }) => ( {tool} ); const HostTag = ({ host }) => {host}; const StatusDot = ({ status }) => ; // Filter chip popover const FilterPopover = ({ dim, value, onPick, onClose, anchor }) => { const ref = React.useRef(null); React.useEffect(() => { const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) onClose(); }; setTimeout(() => document.addEventListener('mousedown', onDoc), 0); return () => document.removeEventListener('mousedown', onDoc); }, [onClose]); const opts = FILTER_DIMS[dim] || []; const top = (anchor?.top || 30) + 4; const left = anchor?.left || 14; return (
{dim}
{opts.map(o => (
{ onPick(o); onClose(); }}> {o}
))}
); }; // Removable filter chip with click-through to popover const FilterChip = ({ dim, value, onChange, onRemove }) => { const [open, setOpen] = React.useState(false); const [anchor, setAnchor] = React.useState(null); const ref = React.useRef(null); return ( <> { const r = ref.current.getBoundingClientRect(); const parent = ref.current.closest('.app').getBoundingClientRect(); setAnchor({ top: r.bottom - parent.top, left: r.left - parent.left }); setOpen(true); }}> {dim}: {value} {onRemove && ( { e.stopPropagation(); onRemove(); }}>× )} {open && setOpen(false)} />} ); }; // Add-filter dashed chip + popover for which dim const AddFilterChip = ({ availableDims, onAdd }) => { const [open, setOpen] = React.useState(false); const [anchor, setAnchor] = React.useState(null); const ref = React.useRef(null); return ( <> { const r = ref.current.getBoundingClientRect(); const parent = ref.current.closest('.app').getBoundingClientRect(); setAnchor({ top: r.bottom - parent.top, left: r.left - parent.left }); setOpen(true); }}>+ filter {open && (
setOpen(false)}>
add filter
{availableDims.map(d => (
{ onAdd(d); setOpen(false); }}> {d}
))}
)} ); }; const Empty = ({ glyph = '∅', title, hint }) => (
{glyph}
{title}
{hint &&
{hint}
}
); Object.assign(window, { Spark, ToolDot, ToolTag, HostTag, StatusDot, FilterPopover, FilterChip, AddFilterChip, Empty, });