From c9e7e4f1e09fdb8db965d5b1e0ee0c56c58df95d Mon Sep 17 00:00:00 2001 From: Test User Date: Sat, 20 Dec 2025 11:57:50 -0500 Subject: [PATCH] refactor: Improve layout and organization of KanbanCard component - Adjusted spacing and alignment in the KanbanCard component for better visual consistency. - Refactored badge rendering logic to use a more compact layout, enhancing readability. - Cleaned up code formatting for improved maintainability and clarity. - Updated Card component styles to ensure consistent padding and margins. --- apps/ui/src/components/ui/card.tsx | 5 +- .../board-view/components/kanban-card.tsx | 352 ++++++++++-------- 2 files changed, 192 insertions(+), 165 deletions(-) diff --git a/apps/ui/src/components/ui/card.tsx b/apps/ui/src/components/ui/card.tsx index f36b6678..3e04be89 100644 --- a/apps/ui/src/components/ui/card.tsx +++ b/apps/ui/src/components/ui/card.tsx @@ -11,11 +11,12 @@ function Card({ className, gradient = false, ...props }: CardProps) {
(null); const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false); const [currentTime, setCurrentTime] = useState(() => Date.now()); - const { kanbanCardDetailLevel, enableDependencyBlocking, features, useWorktrees } = useAppStore(); + const { + kanbanCardDetailLevel, + enableDependencyBlocking, + features, + useWorktrees, + } = useAppStore(); // Calculate blocking dependencies (if feature is in backlog and has incomplete dependencies) const blockingDependencies = useMemo(() => { @@ -287,9 +291,8 @@ export const KanbanCard = memo(function KanbanCard({ (borderStyle as Record).borderColor = "transparent"; } else if (cardBorderOpacity !== 100) { (borderStyle as Record).borderWidth = "1px"; - ( - borderStyle as Record - ).borderColor = `color-mix(in oklch, var(--border) ${cardBorderOpacity}%, transparent)`; + (borderStyle as Record).borderColor = + `color-mix(in oklch, var(--border) ${cardBorderOpacity}%, transparent)`; } const cardElement = ( @@ -336,152 +339,169 @@ export const KanbanCard = memo(function KanbanCard({ /> )} - {/* Priority badge */} - {feature.priority && ( - - - -
- {feature.priority === 1 ? "H" : feature.priority === 2 ? "M" : "L"} -
-
- -

- {feature.priority === 1 - ? "High Priority" - : feature.priority === 2 - ? "Medium Priority" - : "Low Priority"} -

-
-
-
- )} - - {/* Category text next to priority badge */} - {feature.priority && ( -
- - {feature.category} - -
- )} - - {/* Skip Tests (Manual) indicator badge - positioned at top right */} - {feature.skipTests && !feature.error && feature.status === "backlog" && ( - - - -
- -
-
- -

Manual verification required

-
-
-
- )} - - {/* Error indicator badge */} - {feature.error && ( - - - -
- -
-
- -

{feature.error}

-
-
-
- )} - - {/* Blocked by dependencies badge - positioned at top right */} - {blockingDependencies.length > 0 && !feature.error && !feature.skipTests && feature.status === "backlog" && ( - - - -
- -
-
- -

Blocked by {blockingDependencies.length} incomplete {blockingDependencies.length === 1 ? 'dependency' : 'dependencies'}

-

- {blockingDependencies.map(depId => { - const dep = features.find(f => f.id === depId); - return dep?.description || depId; - }).join(', ')} -

-
-
-
- )} - - {/* Just Finished indicator badge */} - {isJustFinished && ( -
0 && + !feature.error && + !feature.skipTests && + feature.status === "backlog") || + isJustFinished) && ( +
+ {/* Error badge */} + {feature.error && ( + + + +
+ +
+
+ +

{feature.error}

+
+
+
+ )} + + {/* Blocked badge */} + {blockingDependencies.length > 0 && + !feature.error && + !feature.skipTests && + feature.status === "backlog" && ( + + + +
+ +
+
+ +

+ Blocked by {blockingDependencies.length} incomplete{" "} + {blockingDependencies.length === 1 + ? "dependency" + : "dependencies"} +

+

+ {blockingDependencies + .map((depId) => { + const dep = features.find((f) => f.id === depId); + return dep?.description || depId; + }) + .join(", ")} +

+
+
+
+ )} + + {/* Just Finished badge */} + {isJustFinished && ( +
+ +
)} - data-testid={`just-finished-badge-${feature.id}`} - title="Agent just finished working on this feature" - > -
)} - + + {feature.category} + +
+ + + {/* Priority and Manual Verification badges - top left, aligned with delete button */} + {(feature.priority || + (feature.skipTests && + !feature.error && + feature.status === "backlog")) && ( +
+ {/* Priority badge */} + {feature.priority && ( + + + +
+ {feature.priority === 1 + ? "H" + : feature.priority === 2 + ? "M" + : "L"} +
+
+ +

+ {feature.priority === 1 + ? "High Priority" + : feature.priority === 2 + ? "Medium Priority" + : "Low Priority"} +

+
+
+
+ )} + {/* Manual verification badge */} + {feature.skipTests && + !feature.error && + feature.status === "backlog" && ( + + + +
+ +
+
+ +

Manual verification required

+
+
+
+ )} +
)} - > {isCurrentAutoTask && (
@@ -522,7 +542,9 @@ export const KanbanCard = memo(function KanbanCard({
- {formatModelName(feature.model ?? DEFAULT_MODEL)} + + {formatModelName(feature.model ?? DEFAULT_MODEL)} +
@@ -561,7 +583,9 @@ export const KanbanCard = memo(function KanbanCard({ }} onPointerDown={(e) => e.stopPropagation()} data-testid={`edit-${ - feature.status === "waiting_approval" ? "waiting" : "verified" + feature.status === "waiting_approval" + ? "waiting" + : "verified" }-${feature.id}`} title="Edit" > @@ -597,7 +621,9 @@ export const KanbanCard = memo(function KanbanCard({ }} onPointerDown={(e) => e.stopPropagation()} data-testid={`delete-${ - feature.status === "waiting_approval" ? "waiting" : "verified" + feature.status === "waiting_approval" + ? "waiting" + : "verified" }-${feature.id}`} title="Delete" > @@ -665,7 +691,9 @@ export const KanbanCard = memo(function KanbanCard({
- {formatModelName(feature.model ?? DEFAULT_MODEL)} + + {formatModelName(feature.model ?? DEFAULT_MODEL)} +
@@ -686,7 +714,9 @@ export const KanbanCard = memo(function KanbanCard({ {feature.titleGenerating ? (
- Generating title... + + Generating title... +
) : feature.title ? ( @@ -724,16 +754,11 @@ export const KanbanCard = memo(function KanbanCard({ )} )} - {!feature.priority && ( - - {feature.category} - - )}
- + {/* Target Branch Display */} {useWorktrees && feature.branchName && (
@@ -746,8 +771,9 @@ export const KanbanCard = memo(function KanbanCard({ {/* PR URL Display */} {typeof feature.prUrl === "string" && - /^https?:\/\//i.test(feature.prUrl) && (() => { - const prNumber = feature.prUrl.split('/').pop(); + /^https?:\/\//i.test(feature.prUrl) && + (() => { + const prNumber = feature.prUrl.split("/").pop(); return (
- {prNumber ? `Pull Request #${prNumber}` : 'Pull Request'} + {prNumber ? `Pull Request #${prNumber}` : "Pull Request"} @@ -953,11 +979,11 @@ export const KanbanCard = memo(function KanbanCard({ )} {/* Actions */} -
+
{isCurrentAutoTask && ( <> {/* Approve Plan button - PRIORITY: shows even when agent is "running" (paused for approval) */} - {feature.planSpec?.status === 'generated' && onApprovePlan && ( + {feature.planSpec?.status === "generated" && onApprovePlan && (