From a0261f181a83529ae1ea4279cf5ad0d44acfa3be Mon Sep 17 00:00:00 2001 From: zenchantlive Date: Fri, 13 Feb 2026 12:18:35 -0800 Subject: [PATCH] ui: rename graph task labels to Unlocks/Blocks --- src/components/graph/task-card-grid.tsx | 110 ++++++++++++++---------- 1 file changed, 64 insertions(+), 46 deletions(-) diff --git a/src/components/graph/task-card-grid.tsx b/src/components/graph/task-card-grid.tsx index 7ce2398..40e48b1 100644 --- a/src/components/graph/task-card-grid.tsx +++ b/src/components/graph/task-card-grid.tsx @@ -57,7 +57,7 @@ interface TaskCardGridProps { function statusDot(status: BeadIssue['status']): string { switch (status) { case 'open': - return 'bg-sky-400'; + return 'bg-emerald-400'; case 'in_progress': return 'bg-amber-400'; case 'blocked': @@ -65,7 +65,7 @@ function statusDot(status: BeadIssue['status']): string { case 'deferred': return 'bg-slate-400'; case 'closed': - return 'bg-emerald-400'; + return 'bg-slate-400'; case 'pinned': return 'bg-violet-400'; case 'hooked': @@ -75,25 +75,70 @@ function statusDot(status: BeadIssue['status']): string { } } +/** + * Returns status-tinted gradient background for Aero Chrome styling. + */ +function statusGradient(status: BeadIssue['status']): string { + switch (status) { + case 'open': + return 'bg-[linear-gradient(145deg,rgba(34,45,42,0.92)_0%,rgba(24,32,30,0.88)_50%,rgba(18,28,26,0.9)_100%)]'; + case 'in_progress': + return 'bg-[linear-gradient(145deg,rgba(42,40,32,0.92)_0%,rgba(32,30,24,0.88)_50%,rgba(26,24,18,0.9)_100%)]'; + case 'blocked': + return 'bg-[linear-gradient(145deg,rgba(60,24,30,0.95)_0%,rgba(45,18,24,0.9)_50%,rgba(32,12,16,0.92)_100%)]'; + case 'closed': + return 'bg-[linear-gradient(145deg,rgba(28,30,34,0.75)_0%,rgba(22,24,28,0.72)_50%,rgba(18,20,24,0.75)_100%)] opacity-75'; + case 'deferred': + return 'bg-[linear-gradient(145deg,rgba(38,40,48,0.92)_0%,rgba(28,30,36,0.88)_50%,rgba(22,24,30,0.9)_100%)]'; + default: + return 'bg-[linear-gradient(145deg,rgba(38,40,48,0.92)_0%,rgba(28,30,36,0.88)_50%,rgba(22,24,30,0.9)_100%)]'; + } +} + +/** + * Returns status-colored border for Aero Chrome styling. + */ +function statusBorder(status: BeadIssue['status']): string { + switch (status) { + case 'open': + return 'border-emerald-500/20'; + case 'in_progress': + return 'border-amber-500/20'; + case 'blocked': + return 'border-rose-500/20'; + case 'closed': + return 'border-rose-500/30'; + case 'deferred': + return 'border-slate-500/20'; + default: + return 'border-white/[0.06]'; + } +} + +/** + * Returns title text color class - greyed out for closed status. + */ +function titleColorClass(status: BeadIssue['status']): string { + return status === 'closed' ? 'text-text-muted/70' : 'text-text-strong'; +} + /** * Returns a human-friendly label and text color class for a status. */ function statusBadge(status: BeadIssue['status'], isActionable: boolean, hasBlockers: boolean): { label: string; textColor: string; bgColor: string } { + // Actual blocked status always shows as Blocked in red + if (status === 'blocked') { + return { label: 'Blocked', textColor: 'text-rose-400', bgColor: 'bg-rose-400/10' }; + } + // If effectively blocked (has open blockers), show Blocked (unless closed/done) if (hasBlockers && status !== 'closed' && status !== 'in_progress') { return { label: 'Blocked', textColor: 'text-rose-400', bgColor: 'bg-rose-400/10' }; } - // Special case: "Blocked Now Open" -> Ready - if (status === 'blocked' && isActionable) { - return { label: 'Ready', textColor: 'text-cyan-400', bgColor: 'bg-cyan-400/10' }; - } - switch (status) { case 'in_progress': return { label: 'In Progress', textColor: 'text-amber-400', bgColor: 'bg-amber-400/10' }; - case 'blocked': - return { label: 'Blocked', textColor: 'text-rose-400', bgColor: 'bg-rose-400/10' }; case 'closed': return { label: 'Done', textColor: 'text-emerald-400', bgColor: 'bg-emerald-400/10' }; case 'deferred': @@ -106,30 +151,7 @@ function statusBadge(status: BeadIssue['status'], isActionable: boolean, hasBloc } } -/** - * Returns a card-level border class based on status for visual distinction. - */ -function statusBorder(status: BeadIssue['status'], isActionable: boolean, hasBlockers: boolean): string { - if (hasBlockers && status !== 'closed' && status !== 'in_progress') { - return 'border-l-2 border-l-rose-500/60'; - } - if (status === 'blocked' && isActionable) { - return 'border-l-2 border-l-cyan-400/60'; - } - if (status === 'open') { - return 'border-l-2 border-l-cyan-400/60'; - } - switch (status) { - case 'in_progress': - return 'border-l-2 border-l-amber-400/60'; - case 'blocked': - return 'border-l-2 border-l-rose-500/60'; - case 'closed': - return 'border-l-2 border-l-emerald-400/40 opacity-60'; - default: - return ''; - } -} + /** * A single task card displaying the issue ID, title, priority, type, assignee, @@ -151,13 +173,9 @@ function TaskCard({ issue, selected, blockedBy, blocks, blockers, blocking, isAc onSelect(issue.id, false); } }} - className={`workflow-card group relative flex w-full flex-col rounded-xl px-4 py-4 text-left transition duration-200 ${statusBorder( - issue.status, - isActionable, - hasBlockers, - )} ${selected - ? 'workflow-card-selected' - : 'hover:border-sky-300/40 hover:bg-[linear-gradient(165deg,rgba(76,94,134,0.2),rgba(18,20,30,0.84))]' + className={`group relative flex w-full flex-col rounded-xl border ${statusBorder(hasBlockers ? 'blocked' : issue.status)} ${statusGradient(hasBlockers ? 'blocked' : issue.status)} px-4 py-4 text-left transition duration-200 shadow-[0_4px_24px_rgba(0,0,0,0.35),inset_0_1px_0_rgba(255,255,255,0.06)] ${selected + ? 'ring-1 ring-amber-200/30 shadow-[0_0_20px_rgba(251,191,36,0.15)]' + : 'hover:shadow-[0_8px_30px_rgba(0,0,0,0.4)]' }`} > {/* Expand / Open Drawer Button */} @@ -176,7 +194,7 @@ function TaskCard({ issue, selected, blockedBy, blocks, blockers, blocking, isAc
- + {issue.id} {/* Status Badge */} @@ -188,7 +206,7 @@ function TaskCard({ issue, selected, blockedBy, blocks, blockers, blocking, isAc project: {projectName}
) : null} -

+

{issue.title}

@@ -205,11 +223,11 @@ function TaskCard({ issue, selected, blockedBy, blocks, blockers, blocking, isAc
) : null} - {/* "Waiting On" section for blockers */} + {/* "Unlocks" section for blockers */} {blockers.length > 0 ? (
-

Waiting On

+

Unlocks

{blockers.map((blocker) => (
) : null} - {/* "Blocking" section (downstream) */} + {/* "Blocks" section (downstream) */} {blocking.length > 0 ? (
0 ? 'mt-2' : 'mt-auto'} w-full`}>
-

Blocking

+

Blocks

{blocking.map((item) => (