feat(app): status rings on panels + sidebar aggregate badge from state events
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+16
-2
@@ -1,4 +1,18 @@
|
||||
import type { Group, WorkspaceView } from "./layoutTypes";
|
||||
import type { Group, WorkspaceView, SurfaceState } from "./layoutTypes";
|
||||
|
||||
const RING: Record<SurfaceState | "stopped", string> = {
|
||||
error: "#F4544E", wait: "#F2B84B", work: "#4C8DFF", done: "#3FB950", idle: "#5A6573", stopped: "#5A6573",
|
||||
};
|
||||
|
||||
function aggregate(w: WorkspaceView): SurfaceState | "stopped" {
|
||||
const order: SurfaceState[] = ["error", "wait", "work", "done", "idle"];
|
||||
const running = Object.values(w.surfaces).filter((s) => s.running);
|
||||
if (running.length === 0) return "stopped";
|
||||
for (const st of order) {
|
||||
if (running.some((s) => s.state === st)) return st;
|
||||
}
|
||||
return "idle";
|
||||
}
|
||||
|
||||
export function Sidebar({
|
||||
groups, workspaces, activeId, onSelect, onNew,
|
||||
@@ -19,7 +33,7 @@ export function Sidebar({
|
||||
background: w.id === activeId ? "#1A2029" : "transparent", fontFamily: "Inter", fontSize: 13,
|
||||
color: w.id === activeId ? "#E6EDF3" : "#8B97A6",
|
||||
}}>
|
||||
<span style={{ width: 10, height: 10, borderRadius: "50%", border: "2px solid #5A6573" }} />
|
||||
<span style={{ width: 10, height: 10, borderRadius: "50%", border: `2px solid ${RING[aggregate(w)]}`, boxSizing: "border-box" }} />
|
||||
<span style={{ flex: 1 }}>{w.name}</span>
|
||||
{w.unread && <span style={{ width: 7, height: 7, borderRadius: "50%", background: "#4C8DFF" }} />}
|
||||
<span style={{ fontFamily: "monospace", fontSize: 11, color: "#5A6573" }}>{Object.keys(w.surfaces).length}</span>
|
||||
|
||||
Reference in New Issue
Block a user