From 0f70cca905c0e7c48d2bb04b7746be7cc03ff16c Mon Sep 17 00:00:00 2001 From: chihlasm Date: Tue, 24 Mar 2026 23:09:59 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20restyle=20branch=20sidebar=20=E2=80=94?= =?UTF-8?q?=20real=20cards,=20scale=20animation,=20visible=20labels?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BranchMap header: - GitBranch icon: text-muted → text-accent-text - "Branch Map" label: text-muted → text-muted-foreground - Count: text-muted → text-muted-foreground with font-medium BranchNode cards: - Now proper cards: bg-card/60 with 1px border-default, rounded-lg, p-2.5 - Active card: accent-tinted border, subtle glow - Hover animation: scale(1.02) + shadow — card lifts toward the user instead of expanding downward - Detail section: uses scale-y transform from origin-top, feels like the card is growing rather than content sliding down - Status-aware border colors (accent/success/danger/warning) - Detail labels ("Tried:", "Result:") now text-foreground font-medium instead of invisible text-muted - Depth indentation via marginLeft instead of paddingLeft Co-Authored-By: Claude Opus 4.6 (1M context) --- frontend/src/components/session/BranchMap.tsx | 34 ++--- .../src/components/session/BranchNode.tsx | 137 ++++++++++-------- 2 files changed, 92 insertions(+), 79 deletions(-) diff --git a/frontend/src/components/session/BranchMap.tsx b/frontend/src/components/session/BranchMap.tsx index 7a39041c..e0fd7cd7 100644 --- a/frontend/src/components/session/BranchMap.tsx +++ b/frontend/src/components/session/BranchMap.tsx @@ -12,12 +12,10 @@ function buildTree(branches: BranchResponse[]): BranchTreeNode[] { const map = new Map() const roots: BranchTreeNode[] = [] - // First pass: create nodes for (const branch of branches) { map.set(branch.id, { branch, depth: 0, children: [] }) } - // Second pass: assign parents / roots for (const branch of branches) { const node = map.get(branch.id)! if (branch.parent_branch_id && map.has(branch.parent_branch_id)) { @@ -54,27 +52,29 @@ export function BranchMap({ branches, activeBranchId, onSelectBranch }: BranchMa const flat = flattenTree(roots) return ( -
-
- - +
+
+ + Branch Map - {branches.length} + {branches.length}
{flat.length === 0 ? ( -

No branches yet.

+

No branches yet.

) : ( - flat.map(({ branch, depth }) => ( - - )) +
+ {flat.map(({ branch, depth }) => ( + + ))} +
)}
) diff --git a/frontend/src/components/session/BranchNode.tsx b/frontend/src/components/session/BranchNode.tsx index 4d78a015..cf9a1f9c 100644 --- a/frontend/src/components/session/BranchNode.tsx +++ b/frontend/src/components/session/BranchNode.tsx @@ -9,6 +9,7 @@ interface StatusConfig { icon: React.ElementType textClass: string badgeClass: string + borderClass: string label: string } @@ -17,30 +18,35 @@ const STATUS_CONFIG: Record = { icon: CircleDot, textClass: 'text-accent', badgeClass: 'bg-accent-dim text-accent-text', + borderClass: 'border-accent/40', label: 'Active', }, solved: { icon: CheckCircle2, textClass: 'text-success', badgeClass: 'bg-success-dim text-success', + borderClass: 'border-success/30', label: 'Solved', }, dead_end: { icon: XCircle, textClass: 'text-danger', badgeClass: 'bg-danger-dim text-danger', + borderClass: 'border-danger/30', label: 'Dead End', }, untried: { icon: Circle, - textClass: 'text-muted', - badgeClass: 'bg-elevated text-muted', + textClass: 'text-muted-foreground', + badgeClass: 'bg-elevated text-muted-foreground', + borderClass: 'border-default', label: 'Untried', }, revived: { icon: RotateCcw, textClass: 'text-warning', badgeClass: 'bg-warning-dim text-warning', + borderClass: 'border-warning/30', label: 'Revived', }, } @@ -60,79 +66,86 @@ export function BranchNode({ branch, depth, isActive, onClick }: BranchNodeProps return (
setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} > + {/* Header row */} +
+ + + {branch.label} + + + {config.label} + +
- {/* Expandable detail panel */} -
-
- {branch.context_summary ? ( - <> - {branch.context_summary.tried.length > 0 && ( -

- Tried:{' '} - {branch.context_summary.tried.join(', ')} -

- )} - {branch.context_summary.concluded && ( -

- Result:{' '} - {branch.context_summary.concluded} -

- )} - - ) : ( -

No activity yet

+ {/* Detail section — animates from scale-y-0 to scale-y-100 */} +
- Reason:{' '} - {branch.status_reason} -

- )} -
- {branch.step_count} step{branch.step_count !== 1 ? 's' : ''} + > +
+ {branch.context_summary ? ( + <> + {branch.context_summary.tried.length > 0 && ( +

+ Tried:{' '} + {branch.context_summary.tried.join(', ')} +

+ )} + {branch.context_summary.concluded && ( +

+ Result:{' '} + {branch.context_summary.concluded} +

+ )} + + ) : ( +

No activity yet

+ )} + {branch.status_reason && ( +

+ Reason:{' '} + {branch.status_reason} +

+ )} +
+ {branch.step_count} step{branch.step_count !== 1 ? 's' : ''} +
-
+
) }