// Adapted from jalcoui (MIT) — github.com/jal-co/ui 'use client'; import * as React from 'react'; import { ArrowDownToLine, Circle, Pause, Play, Search, Terminal, Trash2, X, } from 'lucide-react'; import { cn } from '@djangocfg/ui-core/lib'; import type { LogLevel } from '../types'; import { LEVEL_LABELS, getLevelToneClasses } from '../types'; interface ToolbarButtonProps { onClick: () => void; label: string; active?: boolean; children: React.ReactNode; } function ToolbarButton({ onClick, label, active, children }: ToolbarButtonProps) { return ( ); } export interface ToolbarProps { title: string; totalCount: number; filteredCount: number; levels: LogLevel[]; activeLevels: Set; toggleLevel: (level: LogLevel) => void; levelCounts: Partial>; searchQuery: string; setSearchQuery: (q: string) => void; autoScrollEnabled: boolean; paused: boolean; setPaused: (p: boolean) => void; onClear?: () => void; } /** * Header + filter row for the LogViewer. The level chips also serve as * the count badges — clicking strikes them out and removes the level * from the active set. The search input is always visible (no expand / * collapse toggle) because filter and search are the two main jobs of * the toolbar; hiding either is friction. */ export function Toolbar({ title, totalCount, filteredCount, levels, activeLevels, toggleLevel, levelCounts, searchQuery, setSearchQuery, autoScrollEnabled, paused, setPaused, onClear, }: ToolbarProps) { return (
{title} {filteredCount} {filteredCount !== totalCount && ` / ${totalCount}`} lines
{autoScrollEnabled && ( setPaused(!paused)} label={paused ? 'Resume auto-scroll' : 'Pause auto-scroll'} active={paused} > {paused ? ( ) : ( )} )} {onClear && ( )}
{levels.map((level) => { const tone = getLevelToneClasses(level); const isActive = activeLevels.has(level); const count = levelCounts[level] ?? 0; return ( ); })}
setSearchQuery(e.target.value)} placeholder="Filter…" aria-label="Filter logs" className="w-32 bg-transparent text-xs text-foreground outline-none placeholder:text-muted-foreground sm:w-40" /> {searchQuery && ( )}
); } export interface ScrollToBottomPillProps { visible: boolean; onClick: () => void; } export function ScrollToBottomPill({ visible, onClick }: ScrollToBottomPillProps) { if (!visible) return null; return ( ); }