feat(kanban): enhance Kanban card detail level settings

- Introduced a new feature to control the level of detail displayed on Kanban cards, allowing users to choose between minimal, standard, and detailed views.
- Updated the SettingsView to include buttons for selecting the desired detail level, with corresponding descriptions for each option.
- Integrated the new detail level setting into the KanbanCard component to conditionally render information based on user preferences.

This enhancement improves user experience by providing customizable visibility of feature information on Kanban cards.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
This commit is contained in:
Kacper
2025-12-10 00:02:24 +01:00
parent b901d2bb6c
commit a2d27b94bc
4 changed files with 105 additions and 293 deletions

View File

@@ -20,7 +20,7 @@ import {
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { Feature } from "@/store/app-store";
import { Feature, useAppStore } from "@/store/app-store";
import {
GripVertical,
Edit,
@@ -94,6 +94,12 @@ export function KanbanCard({
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
const [isSummaryDialogOpen, setIsSummaryDialogOpen] = useState(false);
const [agentInfo, setAgentInfo] = useState<AgentTaskInfo | null>(null);
const { kanbanCardDetailLevel } = useAppStore();
// Helper functions to check what should be shown based on detail level
const showSteps = kanbanCardDetailLevel === "standard" || kanbanCardDetailLevel === "detailed";
const showAgentInfo = kanbanCardDetailLevel === "detailed";
const showProgressBar = kanbanCardDetailLevel === "standard" || kanbanCardDetailLevel === "detailed";
// Load context file for in_progress, waiting_approval, and verified features
useEffect(() => {
@@ -261,8 +267,8 @@ export function KanbanCard({
</div>
</CardHeader>
<CardContent className="p-3 pt-0">
{/* Steps Preview */}
{feature.steps.length > 0 && (
{/* Steps Preview - Show in Standard and Detailed modes */}
{showSteps && feature.steps.length > 0 && (
<div className="mb-3 space-y-1">
{feature.steps.slice(0, 3).map((step, index) => (
<div
@@ -286,9 +292,25 @@ export function KanbanCard({
)}
{/* Agent Info Panel - shows for in_progress, waiting_approval, verified */}
{feature.status !== "backlog" && agentInfo && (
{/* Standard mode: Only show progress bar */}
{showProgressBar && !showAgentInfo && feature.status !== "backlog" && agentInfo && (isCurrentAutoTask || feature.status === "in_progress") && (
<div className="mb-3 space-y-1">
<div className="w-full h-1.5 bg-zinc-800 rounded-full overflow-hidden">
<div
className="w-full h-full bg-primary transition-transform duration-500 ease-out origin-left"
style={{ transform: `translateX(${agentInfo.progressPercentage - 100}%)` }}
/>
</div>
<div className="flex items-center justify-between text-[10px] text-muted-foreground">
<span>{Math.round(agentInfo.progressPercentage)}%</span>
</div>
</div>
)}
{/* Detailed mode: Show all agent info */}
{showAgentInfo && feature.status !== "backlog" && agentInfo && (
<div className="mb-3 space-y-2">
{/* Model & Progress Bar */}
{/* Model & Phase */}
<div className="flex items-center gap-2 text-xs">
<div className="flex items-center gap-1 text-cyan-400">
<Cpu className="w-3 h-3" />

View File

@@ -6,10 +6,10 @@ import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Settings, Key, Eye, EyeOff, CheckCircle2, AlertCircle, Loader2, Zap, Sun, Moon, Palette } from "lucide-react";
import { Settings, Key, Eye, EyeOff, CheckCircle2, AlertCircle, Loader2, Zap, Sun, Moon, Palette, LayoutGrid, Minimize2, Square, Maximize2 } from "lucide-react";
export function SettingsView() {
const { apiKeys, setApiKeys, setCurrentView, theme, setTheme } = useAppStore();
const { apiKeys, setApiKeys, setCurrentView, theme, setTheme, kanbanCardDetailLevel, setKanbanCardDetailLevel } = useAppStore();
const [anthropicKey, setAnthropicKey] = useState(apiKeys.anthropic);
const [googleKey, setGoogleKey] = useState(apiKeys.google);
const [showAnthropicKey, setShowAnthropicKey] = useState(false);
@@ -353,6 +353,70 @@ export function SettingsView() {
</div>
</div>
{/* Kanban Card Display Section */}
<div className="rounded-xl border border-white/10 bg-zinc-900/50 backdrop-blur-md overflow-hidden">
<div className="p-6 border-b border-white/10">
<div className="flex items-center gap-2 mb-2">
<LayoutGrid className="w-5 h-5 text-brand-500" />
<h2 className="text-lg font-semibold text-white">Kanban Card Display</h2>
</div>
<p className="text-sm text-zinc-400">
Control how much information is displayed on Kanban cards.
</p>
</div>
<div className="p-6 space-y-4">
<div className="space-y-3">
<Label className="text-zinc-300">Detail Level</Label>
<div className="grid grid-cols-3 gap-3">
<button
onClick={() => setKanbanCardDetailLevel("minimal")}
className={`flex flex-col items-center justify-center gap-2 px-4 py-4 rounded-lg border transition-all ${
kanbanCardDetailLevel === "minimal"
? "bg-white/5 border-brand-500 text-white"
: "bg-zinc-950/50 border-white/10 text-zinc-400 hover:text-white hover:bg-white/5"
}`}
data-testid="kanban-detail-minimal"
>
<Minimize2 className="w-5 h-5" />
<span className="font-medium text-sm">Minimal</span>
<span className="text-xs text-zinc-500 text-center">Title & category only</span>
</button>
<button
onClick={() => setKanbanCardDetailLevel("standard")}
className={`flex flex-col items-center justify-center gap-2 px-4 py-4 rounded-lg border transition-all ${
kanbanCardDetailLevel === "standard"
? "bg-white/5 border-brand-500 text-white"
: "bg-zinc-950/50 border-white/10 text-zinc-400 hover:text-white hover:bg-white/5"
}`}
data-testid="kanban-detail-standard"
>
<Square className="w-5 h-5" />
<span className="font-medium text-sm">Standard</span>
<span className="text-xs text-zinc-500 text-center">Steps & progress</span>
</button>
<button
onClick={() => setKanbanCardDetailLevel("detailed")}
className={`flex flex-col items-center justify-center gap-2 px-4 py-4 rounded-lg border transition-all ${
kanbanCardDetailLevel === "detailed"
? "bg-white/5 border-brand-500 text-white"
: "bg-zinc-950/50 border-white/10 text-zinc-400 hover:text-white hover:bg-white/5"
}`}
data-testid="kanban-detail-detailed"
>
<Maximize2 className="w-5 h-5" />
<span className="font-medium text-sm">Detailed</span>
<span className="text-xs text-zinc-500 text-center">Model, tools & tasks</span>
</button>
</div>
<p className="text-xs text-zinc-500">
<strong>Minimal:</strong> Shows only title and category<br />
<strong>Standard:</strong> Adds steps preview and progress bar<br />
<strong>Detailed:</strong> Shows all info including model, tool calls, task list, and summaries
</p>
</div>
</div>
</div>
{/* Save Button */}
<div className="flex items-center gap-4">
<Button