From 789b74219e2b8ef3d83eb065164a97b76dc05411 Mon Sep 17 00:00:00 2001 From: iliya Date: Sat, 28 Mar 2026 12:52:46 +0200 Subject: [PATCH] =?UTF-8?q?feat(graph):=20redesign=20toolbar=20=E2=80=94?= =?UTF-8?q?=20icons,=20team=20color,=20no=20system=20button=20overlap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Toolbar moved to top-10 (below macOS system buttons) - Lucide icons for all buttons (Tasks, Proc, Edges, Play/Pause, Zoom, Pin, Close) - Toggle buttons show active state with highlight background - Team name + alive indicator uses team color from config - Grouped buttons in glass panels with backdrop-blur - Removed raw text-only buttons (was: "−", "⊡", "+", "⊞ Pin", "✕") --- packages/agent-graph/src/ui/GraphControls.tsx | 148 ++++++++++++++---- packages/agent-graph/src/ui/GraphView.tsx | 1 + 2 files changed, 116 insertions(+), 33 deletions(-) diff --git a/packages/agent-graph/src/ui/GraphControls.tsx b/packages/agent-graph/src/ui/GraphControls.tsx index d3537463..d593b10d 100644 --- a/packages/agent-graph/src/ui/GraphControls.tsx +++ b/packages/agent-graph/src/ui/GraphControls.tsx @@ -1,9 +1,22 @@ /** * GraphControls — floating toolbar over the canvas. - * Zoom, fit, filter toggles, pause, pin-as-tab, close. + * Positioned below system buttons (top-10) to avoid overlap on macOS. */ import { useCallback } from 'react'; +import { + Columns3, + Eye, + EyeOff, + Maximize2, + Minus, + Pause, + Pin, + Play, + Plus, + Server, + X, +} from 'lucide-react'; export interface GraphFilterState { showTasks: boolean; @@ -21,6 +34,7 @@ export interface GraphControlsProps { onRequestClose?: () => void; onRequestPinAsTab?: () => void; teamName: string; + teamColor?: string; isAlive?: boolean; } @@ -33,6 +47,7 @@ export function GraphControls({ onRequestClose, onRequestPinAsTab, teamName, + teamColor, isAlive, }: GraphControlsProps): React.JSX.Element { const toggle = useCallback( @@ -42,72 +57,139 @@ export function GraphControls({ [filters, onFiltersChange], ); + const nameColor = teamColor ?? '#aaeeff'; + return ( -
- {/* Left: title + status */} -
-
+
+ {/* Left: team name + status indicator */} +
+
{isAlive && ( -
+
)} - + {teamName}
- {/* Center: filters */} -
- toggle('showTasks')} label="Tasks" /> - toggle('showProcesses')} label="Proc" /> - toggle('showEdges')} label="Edges" /> -
- toggle('paused')} label={filters.paused ? '▶' : '⏸'} /> + {/* Center: filter toggles */} +
+ toggle('showTasks')} + icon={} + label="Tasks" + /> + toggle('showProcesses')} + icon={} + label="Proc" + /> + toggle('showEdges')} + icon={filters.showEdges ? : } + label="Edges" + /> + + toggle('paused')} + icon={filters.paused ? : } + />
{/* Right: zoom + actions */} -
- - - +
+ } /> + } /> + } /> {onRequestPinAsTab && ( <> -
- + + } + label="Pin" + /> )} {onRequestClose && ( - + } /> )}
); } -// ─── Toolbar Button ───────────────────────────────────────────────────────── +// ─── Primitives ───────────────────────────────────────────────────────────── function ToolbarButton({ - active, onClick, + icon, label, }: { - active?: boolean; onClick?: () => void; + icon: React.ReactNode; + label?: string; +}): React.JSX.Element { + return ( + + ); +} + +function ToolbarToggle({ + active, + onClick, + icon, + label, +}: { + active: boolean; + onClick: () => void; + icon: React.ReactNode; label: string; }): React.JSX.Element { return ( ); } + +function Separator(): React.JSX.Element { + return
; +} diff --git a/packages/agent-graph/src/ui/GraphView.tsx b/packages/agent-graph/src/ui/GraphView.tsx index 89c70d4c..bfac037f 100644 --- a/packages/agent-graph/src/ui/GraphView.tsx +++ b/packages/agent-graph/src/ui/GraphView.tsx @@ -328,6 +328,7 @@ export function GraphView({ onRequestClose={onRequestClose} onRequestPinAsTab={onRequestPinAsTab} teamName={data.teamName} + teamColor={data.teamColor} isAlive={data.isAlive} />