fix: update MemberBadge and LaunchTeamDialog components for improved functionality

- Modified MemberBadge to display 'lead' for team leads instead of the full name.
- Refactored LaunchTeamDialog to simplify model selection logic and replace the Select component with a custom button-based interface for better user experience.
- Enhanced KanbanTaskCard to include meta actions for task management, improving the layout and functionality for manual review tasks.
This commit is contained in:
iliya 2026-02-27 13:25:07 +02:00
parent 6a8b9cd1b5
commit 290646bea8
3 changed files with 66 additions and 52 deletions

View file

@ -45,7 +45,7 @@ export const MemberBadge = ({
className={`rounded px-1.5 py-0.5 ${textClass} font-medium tracking-wide`} className={`rounded px-1.5 py-0.5 ${textClass} font-medium tracking-wide`}
style={badgeStyle} style={badgeStyle}
> >
{name} {name === 'team-lead' ? 'lead' : name}
</span> </span>
); );

View file

@ -13,14 +13,8 @@ import {
} from '@renderer/components/ui/dialog'; } from '@renderer/components/ui/dialog';
import { Label } from '@renderer/components/ui/label'; import { Label } from '@renderer/components/ui/label';
import { MentionableTextarea } from '@renderer/components/ui/MentionableTextarea'; import { MentionableTextarea } from '@renderer/components/ui/MentionableTextarea';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@renderer/components/ui/select';
import { useDraftPersistence } from '@renderer/hooks/useDraftPersistence'; import { useDraftPersistence } from '@renderer/hooks/useDraftPersistence';
import { cn } from '@renderer/lib/utils';
import { useStore } from '@renderer/store'; import { useStore } from '@renderer/store';
import { formatAgentRole } from '@renderer/utils/formatAgentRole'; import { formatAgentRole } from '@renderer/utils/formatAgentRole';
import { buildMemberColorMap } from '@renderer/utils/memberHelpers'; import { buildMemberColorMap } from '@renderer/utils/memberHelpers';
@ -246,7 +240,7 @@ export const LaunchTeamDialog = ({
teamName, teamName,
cwd: effectiveCwd, cwd: effectiveCwd,
prompt: promptDraft.value.trim() || undefined, prompt: promptDraft.value.trim() || undefined,
model: selectedModel && selectedModel !== '__default__' ? selectedModel : undefined, model: selectedModel || undefined,
clearContext: clearContext || undefined, clearContext: clearContext || undefined,
}); });
resetFormState(); resetFormState();
@ -361,17 +355,28 @@ export const LaunchTeamDialog = ({
<div className="space-y-1.5"> <div className="space-y-1.5">
<Label className="label-optional">Model (optional)</Label> <Label className="label-optional">Model (optional)</Label>
<Select value={selectedModel} onValueChange={setSelectedModel}> <div className="inline-flex rounded-md border border-[var(--color-border)] bg-[var(--color-surface)] p-0.5">
<SelectTrigger className="h-8 text-xs"> {[
<SelectValue placeholder="Default (account setting)" /> { value: '', label: 'Default' },
</SelectTrigger> { value: 'opus', label: 'Opus 4.6' },
<SelectContent> { value: 'sonnet', label: 'Sonnet 4.5' },
<SelectItem value="__default__">Default (account setting)</SelectItem> { value: 'haiku', label: 'Haiku 4.5' },
<SelectItem value="opus">Opus 4.6</SelectItem> ].map((opt) => (
<SelectItem value="sonnet">Sonnet 4.5</SelectItem> <button
<SelectItem value="haiku">Haiku 4.5</SelectItem> key={opt.value}
</SelectContent> type="button"
</Select> className={cn(
'rounded-[3px] px-3 py-1 text-xs font-medium transition-colors',
selectedModel === opt.value
? 'bg-[var(--color-surface-raised)] text-[var(--color-text)] shadow-sm'
: 'text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]'
)}
onClick={() => setSelectedModel(opt.value)}
>
{opt.label}
</button>
))}
</div>
</div> </div>
<div className="space-y-2"> <div className="space-y-2">

View file

@ -170,6 +170,40 @@ export const KanbanTaskCard = ({
} }
}, [showChangesColumn, task.status, task.id, teamName, taskHasChanges, checkTaskHasChanges]); }, [showChangesColumn, task.status, task.id, teamName, taskHasChanges, checkTaskHasChanges]);
const isReviewManual = columnId === 'review' && !hasReviewers;
const metaActions = (
<>
{showChangesColumn && taskHasChanges === true ? (
<button
type="button"
onClick={(e) => {
e.stopPropagation();
onViewChanges(task.id);
}}
className="flex items-center gap-1 text-[10px] text-[var(--color-text-muted)] transition-colors hover:text-blue-400"
>
<FileCode className="size-3" />
Changes
</button>
) : null}
<UnreadCommentsBadge unreadCount={unreadCount} totalCount={task.comments?.length ?? 0} />
{onDeleteTask ? (
<button
type="button"
onClick={(e) => {
e.stopPropagation();
onDeleteTask(task.id);
}}
className="text-[var(--color-text-muted)] transition-colors hover:text-red-400"
title="Delete task"
>
<Trash2 size={12} />
</button>
) : null}
</>
);
return ( return (
<div <div
data-task-id={task.id} data-task-id={task.id}
@ -335,9 +369,12 @@ export const KanbanTaskCard = ({
) : null} ) : null}
{columnId === 'review' ? ( {columnId === 'review' ? (
<div className="space-y-2"> <div className="w-full space-y-2">
{!hasReviewers ? ( {isReviewManual ? (
<p className="text-[11px] text-[var(--color-text-muted)]">Manual review</p> <div className="flex items-center justify-between">
<p className="text-[11px] text-[var(--color-text-muted)]">Manual review</p>
<div className="flex items-center gap-1.5">{metaActions}</div>
</div>
) : null} ) : null}
<div className="flex gap-2"> <div className="flex gap-2">
<Button <Button
@ -383,35 +420,7 @@ export const KanbanTaskCard = ({
) : null} ) : null}
</div> </div>
<div className="flex items-center gap-1.5"> {!isReviewManual ? <div className="flex items-center gap-1.5">{metaActions}</div> : null}
{showChangesColumn && taskHasChanges === true ? (
<button
type="button"
onClick={(e) => {
e.stopPropagation();
onViewChanges(task.id);
}}
className="flex items-center gap-1 text-[10px] text-[var(--color-text-muted)] transition-colors hover:text-blue-400"
>
<FileCode className="size-3" />
Changes
</button>
) : null}
<UnreadCommentsBadge unreadCount={unreadCount} totalCount={task.comments?.length ?? 0} />
{onDeleteTask ? (
<button
type="button"
onClick={(e) => {
e.stopPropagation();
onDeleteTask(task.id);
}}
className="text-[var(--color-text-muted)] transition-colors hover:text-red-400"
title="Delete task"
>
<Trash2 size={12} />
</button>
) : null}
</div>
</div> </div>
</div> </div>
); );