refactor: clean up GlobalTaskList and enhance TaskDetailDialog

- Removed unnecessary border styling in `GlobalTaskList` for a cleaner layout.
- Added logic in `ActivityTimeline` to identify and set team lead information based on member roles.
- Improved `TaskDetailDialog` to display owner information with enhanced styling and avatar support, utilizing team colors for better visual distinction.
- Streamlined dependency display in `TaskDetailDialog` for improved readability and user interaction.
This commit is contained in:
iliya 2026-02-23 19:58:09 +02:00 committed by Илия
parent 1b6f7be767
commit 361828f21a
3 changed files with 164 additions and 128 deletions

View file

@ -236,10 +236,7 @@ export const GlobalTaskList = ({
</div> </div>
{/* Grouping mode */} {/* Grouping mode */}
<div <div className="flex shrink-0 items-center gap-2 px-2 py-1">
className="flex shrink-0 items-center gap-2 border-b px-2 py-1"
style={{ borderColor: 'var(--color-border)' }}
>
<span className="shrink-0 text-[11px] text-text-muted">Group by:</span> <span className="shrink-0 text-[11px] text-text-muted">Group by:</span>
<Select value={groupingMode} onValueChange={(v) => setGroupingMode(v as TaskGroupingMode)}> <Select value={groupingMode} onValueChange={(v) => setGroupingMode(v as TaskGroupingMode)}>
<SelectTrigger className="h-7 min-w-0 flex-1 border-[var(--color-border)] px-2 text-[11px]"> <SelectTrigger className="h-7 min-w-0 flex-1 border-[var(--color-border)] px-2 text-[11px]">

View file

@ -111,6 +111,18 @@ export const ActivityTimeline = ({
memberInfo.set(m.agentType, info); memberInfo.set(m.agentType, info);
} }
} }
const leadMember = members.find(
(m) => m.agentType === 'team-lead' || m.role?.toLowerCase().includes('lead')
);
if (leadMember) {
const leadInfo = memberInfo.get(leadMember.name);
if (leadInfo) {
const teamLeadColor = leadInfo.color ?? getMemberColorByName('team-lead');
const resolvedLeadInfo = { role: leadInfo.role, color: teamLeadColor };
memberInfo.set('team-lead', resolvedLeadInfo);
memberInfo.set(leadMember.name, resolvedLeadInfo);
}
}
} }
const handleMemberNameClick = (name: string): void => { const handleMemberNameClick = (name: string): void => {

View file

@ -13,8 +13,10 @@ import {
DialogHeader, DialogHeader,
DialogTitle, DialogTitle,
} from '@renderer/components/ui/dialog'; } from '@renderer/components/ui/dialog';
import { getTeamColorSet } from '@renderer/constants/teamColors';
import { markAsRead } from '@renderer/services/commentReadStorage'; import { markAsRead } from '@renderer/services/commentReadStorage';
import { import {
agentAvatarUrl,
KANBAN_COLUMN_DISPLAY, KANBAN_COLUMN_DISPLAY,
TASK_STATUS_LABELS, TASK_STATUS_LABELS,
TASK_STATUS_STYLES, TASK_STATUS_STYLES,
@ -98,6 +100,7 @@ export const TaskDetailDialog = ({
t.id !== currentTask.id && Array.isArray(t.related) && t.related.includes(currentTask.id) t.id !== currentTask.id && Array.isArray(t.related) && t.related.includes(currentTask.id)
) )
.map((t) => t.id); .map((t) => t.id);
const ownerMember = currentTask.owner ? members.find((m) => m.name === currentTask.owner) : null;
return ( return (
<Dialog open={open} onOpenChange={(v) => !v && onClose()}> <Dialog open={open} onOpenChange={(v) => !v && onClose()}>
@ -121,12 +124,34 @@ export const TaskDetailDialog = ({
{/* Metadata */} {/* Metadata */}
<div className="grid grid-cols-2 gap-x-4 gap-y-2 text-xs sm:grid-cols-3"> <div className="grid grid-cols-2 gap-x-4 gap-y-2 text-xs sm:grid-cols-3">
<div className="flex min-w-0 items-center gap-2">
{ownerMember ? (
<div
className="flex min-w-0 items-center gap-2 rounded-md px-2 py-1"
style={{
borderLeft: `3px solid ${getTeamColorSet(ownerMember.color ?? '').border}`,
backgroundColor: getTeamColorSet(ownerMember.color ?? '').badge,
}}
>
<img
src={agentAvatarUrl(ownerMember.name, 32)}
alt={ownerMember.name}
className="size-6 shrink-0 rounded-full bg-[var(--color-surface-raised)]"
loading="lazy"
/>
<span className="min-w-0 truncate font-medium text-[var(--color-text)]">
{ownerMember.name}
</span>
</div>
) : (
<div className="flex items-center gap-1.5 text-[var(--color-text-muted)]"> <div className="flex items-center gap-1.5 text-[var(--color-text-muted)]">
<User size={12} /> <User size={12} />
<span className="text-[var(--color-text-secondary)]"> <span className="text-[var(--color-text-secondary)]">
{currentTask.owner ?? '\u2014'} {currentTask.owner ?? '\u2014'}
</span> </span>
</div> </div>
)}
</div>
{currentTask.createdBy ? ( {currentTask.createdBy ? (
<div className="flex items-center gap-1.5 text-[var(--color-text-muted)]"> <div className="flex items-center gap-1.5 text-[var(--color-text-muted)]">
<PenLine size={12} /> <PenLine size={12} />
@ -159,6 +184,7 @@ export const TaskDetailDialog = ({
)} )}
</CollapsibleTeamSection> </CollapsibleTeamSection>
<div className="mb-3 space-y-2">
{/* Dependencies */} {/* Dependencies */}
{blockedByIds.length > 0 ? ( {blockedByIds.length > 0 ? (
<div className="flex flex-wrap items-center gap-1.5"> <div className="flex flex-wrap items-center gap-1.5">
@ -279,6 +305,7 @@ export const TaskDetailDialog = ({
) : null} ) : null}
</div> </div>
) : null} ) : null}
</div>
{/* Comments */} {/* Comments */}
<CollapsibleTeamSection <CollapsibleTeamSection