import { useState } from 'react'; import { DashboardContainer } from '@hyperdx/common-utils/dist/types'; import { ActionIcon, Flex, Input, Menu, Text } from '@mantine/core'; import { IconChevronRight, IconDotsVertical, IconEye, IconEyeOff, IconPlus, IconTrash, } from '@tabler/icons-react'; export default function SectionHeader({ section, tileCount, collapsed, defaultCollapsed, onToggle, onToggleDefaultCollapsed, onRename, onDelete, onAddTile, }: { section: DashboardContainer; tileCount: number; /** Effective collapsed state (URL state ?? DB default). */ collapsed: boolean; /** The DB-stored default collapsed state. */ defaultCollapsed: boolean; /** Toggle collapse in URL state (chevron click). */ onToggle: () => void; /** Toggle the DB-stored default collapsed state (menu action). */ onToggleDefaultCollapsed?: () => void; onRename?: (newTitle: string) => void; onDelete?: () => void; onAddTile?: () => void; }) { const [editing, setEditing] = useState(false); const [editedTitle, setEditedTitle] = useState(section.title); const [hovered, setHovered] = useState(false); const [menuOpen, setMenuOpen] = useState(false); const showControls = hovered || menuOpen; const hasMenuControls = onDelete != null || onToggleDefaultCollapsed != null; const handleSaveRename = () => { const trimmed = editedTitle.trim(); if (trimmed && trimmed !== section.title) { onRename?.(trimmed); } else { setEditedTitle(section.title); } setEditing(false); }; const handleTitleClick = (e: React.MouseEvent) => { if (!onRename) return; e.stopPropagation(); setEditedTitle(section.title); setEditing(true); }; return ( setHovered(true)} onMouseLeave={() => setHovered(false)} style={{ borderBottom: '1px solid var(--mantine-color-dark-4)', userSelect: 'none', }} data-testid={`section-header-${section.id}`} > { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onToggle(); } } } role="button" tabIndex={editing ? undefined : 0} aria-expanded={!collapsed} aria-label={`Toggle ${section.title} section`} > {editing ? (
{ e.preventDefault(); handleSaveRename(); }} onClick={e => e.stopPropagation()} > setEditedTitle(e.currentTarget.value)} onBlur={handleSaveRename} onKeyDown={e => { if (e.key === 'Escape') { setEditedTitle(section.title); setEditing(false); } }} autoFocus data-testid={`section-rename-input-${section.id}`} />
) : ( <> {section.title} {collapsed && tileCount > 0 && ( ({tileCount} {tileCount === 1 ? 'tile' : 'tiles'}) )} )}
{onAddTile && !editing && ( { e.stopPropagation(); onAddTile(); }} title="Add tile to section" data-testid={`section-add-tile-${section.id}`} style={{ opacity: showControls ? 1 : 0, pointerEvents: showControls ? 'auto' : 'none', }} > )} {hasMenuControls && !editing && ( e.stopPropagation()} data-testid={`section-menu-${section.id}`} style={{ opacity: showControls ? 1 : 0, pointerEvents: showControls ? 'auto' : 'none', }} > {onToggleDefaultCollapsed && ( ) : ( ) } onClick={onToggleDefaultCollapsed} data-testid={`section-toggle-default-${section.id}`} > {defaultCollapsed ? 'Expand by Default' : 'Collapse by Default'} )} {onDelete && ( <> } color="red" onClick={onDelete} data-testid={`section-delete-${section.id}`} > Delete Section )} )}
); }