Thread progressByTaskId through TaskListPanel and TasksScreen

Progress notifications arrive separately from the Task object, so the
parent provides a map of progress data keyed by taskId. TaskListPanel
and TasksScreen accept an optional progressByTaskId prop and pass the
matching entry to each TaskCard.

Updated Mixed story and ConnectedView TasksActive story to demonstrate
the progress bar on the active "working" task.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
cliffhall 2026-04-20 11:07:43 -04:00
commit f9f239c8c7
4 changed files with 23 additions and 0 deletions

View file

@ -10,10 +10,12 @@ import {
} from "@mantine/core";
import type { Task, TaskStatus } from "@modelcontextprotocol/sdk/types.js";
import { TaskCard } from "../TaskCard/TaskCard";
import type { TaskProgress } from "../TaskCard/TaskCard";
import { ListToggle } from "../../elements/ListToggle/ListToggle";
export interface TaskListPanelProps {
tasks: Task[];
progressByTaskId?: Record<string, TaskProgress>;
searchText: string;
statusFilter?: TaskStatus;
onCancel: (taskId: string) => void;
@ -67,6 +69,7 @@ function matchesFilters(
export function TaskListPanel({
tasks,
progressByTaskId,
searchText,
statusFilter,
onCancel,
@ -115,6 +118,7 @@ export function TaskListPanel({
<TaskCard
key={task.taskId}
task={task}
progress={progressByTaskId?.[task.taskId]}
isListExpanded={!compact}
onCancel={() => onCancel(task.taskId)}
/>
@ -136,6 +140,7 @@ export function TaskListPanel({
<TaskCard
key={task.taskId}
task={task}
progress={progressByTaskId?.[task.taskId]}
isListExpanded={!compact}
onCancel={() => onCancel(task.taskId)}
/>

View file

@ -53,6 +53,13 @@ const sampleTasks: Task[] = [
export const Mixed: Story = {
args: {
tasks: sampleTasks,
progressByTaskId: {
d0b22eba71fa36229ce5c4dfadeaa7de: {
progress: 650,
total: 1000,
message: "Processing records...",
},
},
},
};

View file

@ -3,9 +3,11 @@ import { Card, Flex, Stack } from "@mantine/core";
import type { Task, TaskStatus } from "@modelcontextprotocol/sdk/types.js";
import { TaskControls } from "../../groups/TaskControls/TaskControls";
import { TaskListPanel } from "../../groups/TaskListPanel/TaskListPanel";
import type { TaskProgress } from "../../groups/TaskCard/TaskCard";
export interface TasksScreenProps {
tasks: Task[];
progressByTaskId?: Record<string, TaskProgress>;
onRefresh: () => void;
onClearCompleted: () => void;
onCancel: (taskId: string) => void;
@ -30,6 +32,7 @@ const SidebarCard = Card.withProps({
export function TasksScreen({
tasks,
progressByTaskId,
onRefresh,
onClearCompleted,
onCancel,
@ -52,6 +55,7 @@ export function TasksScreen({
</Sidebar>
<TaskListPanel
tasks={tasks}
progressByTaskId={progressByTaskId}
searchText={searchText}
statusFilter={statusFilter}
onCancel={onCancel}

View file

@ -577,6 +577,13 @@ export const TasksActive: Story = {
statusMessage: "Timeout waiting for tool response after 30s",
},
]}
progressByTaskId={{
d0b22eba71fa36229ce5c4dfadeaa7de: {
progress: 650,
total: 1000,
message: "Processing records...",
},
}}
onRefresh={fn()}
onClearCompleted={fn()}
onCancel={fn()}