diff --git a/frontend/src/components/tasks/SharedTaskCard.tsx b/frontend/src/components/tasks/SharedTaskCard.tsx index 21363302..4dd89d56 100644 --- a/frontend/src/components/tasks/SharedTaskCard.tsx +++ b/frontend/src/components/tasks/SharedTaskCard.tsx @@ -1,7 +1,7 @@ import { useCallback, useEffect, useRef } from 'react'; import { KanbanCard } from '@/components/ui/shadcn-io/kanban'; import type { SharedTaskRecord } from '@/hooks/useProjectTasks'; -import { UserAvatar } from './UserAvatar'; +import { TaskCardHeader } from './TaskCardHeader'; interface SharedTaskCardProps { task: SharedTaskRecord; @@ -48,23 +48,22 @@ export function SharedTaskCard({ dragDisabled className="relative overflow-hidden pl-5 before:absolute before:left-0 before:top-0 before:bottom-0 before:w-[3px] before:bg-muted-foreground before:content-['']" > -
- + -
-

- {task.title} -

- {task.description && ( -

- {task.description} -

- )} -
+ {task.description && ( +

+ {task.description.length > 130 + ? `${task.description.substring(0, 130)}...` + : task.description} +

+ )}
); diff --git a/frontend/src/components/tasks/TaskCard.tsx b/frontend/src/components/tasks/TaskCard.tsx index 0577c3a6..618f8b37 100644 --- a/frontend/src/components/tasks/TaskCard.tsx +++ b/frontend/src/components/tasks/TaskCard.tsx @@ -8,7 +8,7 @@ import { useNavigateWithSearch } from '@/hooks'; import { paths } from '@/lib/paths'; import { attemptsApi } from '@/lib/api'; import type { SharedTaskRecord } from '@/hooks/useProjectTasks'; -import { UserAvatar } from './UserAvatar'; +import { TaskCardHeader } from './TaskCardHeader'; import { useTranslation } from 'react-i18next'; type Task = TaskWithAttemptStatus; @@ -93,35 +93,29 @@ export function TaskCard({ : undefined } > -
- {sharedTask ? ( - - ) : null} -
-
-

- {task.title} -

-
- {/* In Progress Spinner */} +
+ {task.has_in_progress_attempt && ( )} - {/* Merged Indicator */} {task.has_merged_attempt && ( )} - {/* Failed Indicator */} {task.last_attempt_failed && !task.has_merged_attempt && ( )} - {/* Parent Task Indicator */} {task.parent_task_attempt && ( )} - {/* Actions Menu */} -
-
- {task.description && ( -

- {task.description.length > 130 - ? `${task.description.substring(0, 130)}...` - : task.description} -

- )} -
+ + } + /> + {task.description && ( +

+ {task.description.length > 130 + ? `${task.description.substring(0, 130)}...` + : task.description} +

+ )}
); diff --git a/frontend/src/components/tasks/TaskCardHeader.tsx b/frontend/src/components/tasks/TaskCardHeader.tsx new file mode 100644 index 00000000..d7b70435 --- /dev/null +++ b/frontend/src/components/tasks/TaskCardHeader.tsx @@ -0,0 +1,47 @@ +import type { ReactNode } from 'react'; +import { UserAvatar } from './UserAvatar'; + +interface HeaderAvatar { + firstName?: string; + lastName?: string; + username?: string; + imageUrl?: string; +} + +interface TaskCardHeaderProps { + title: ReactNode; + avatar?: HeaderAvatar; + right?: ReactNode; + className?: string; + titleClassName?: string; +} + +export function TaskCardHeader({ + title, + avatar, + right, + className, + titleClassName, +}: TaskCardHeaderProps) { + return ( +
+

+ {avatar ? ( + + ) : null} + {title} +

+ {right ? ( +
{right}
+ ) : null} +
+ ); +} diff --git a/frontend/src/components/tasks/UserAvatar.tsx b/frontend/src/components/tasks/UserAvatar.tsx index b6290fd7..98097a6e 100644 --- a/frontend/src/components/tasks/UserAvatar.tsx +++ b/frontend/src/components/tasks/UserAvatar.tsx @@ -99,7 +99,7 @@ export const UserAvatar = ({ return (