Exclude 'done' tasks from parent time estimates

When a leaf task is marked as 'done', it no longer contributes to its parent's
time estimate. This shows remaining work rather than total estimated work.

Example:
- Parent with 2 subtasks (30m each) shows 1h
- Mark one subtask as done → parent now shows 30m
- Mark both done → parent shows 0m (or own estimate if set)

This provides accurate tracking of remaining time across the task hierarchy.
This commit is contained in:
Claude
2025-11-20 09:46:17 +00:00
parent c9555737d8
commit 718e5acbe2

View File

@@ -23,13 +23,14 @@ export function formatTags(tags) {
} }
// Calculate sum of all LEAF descendant estimates (hierarchical structure) // Calculate sum of all LEAF descendant estimates (hierarchical structure)
// Excludes tasks marked as "done"
export function calculateLeafTime(task) { export function calculateLeafTime(task) {
// If no subtasks, this is a leaf - return its own estimate // If no subtasks, this is a leaf - return its own estimate if not done
if (!task.subtasks || task.subtasks.length === 0) { if (!task.subtasks || task.subtasks.length === 0) {
return task.estimated_minutes || 0; return (task.status !== 'done' && task.estimated_minutes) ? task.estimated_minutes : 0;
} }
// Has subtasks, so sum up all leaf descendants // Has subtasks, so sum up all leaf descendants (excluding done tasks)
let total = 0; let total = 0;
for (const subtask of task.subtasks) { for (const subtask of task.subtasks) {
total += calculateLeafTime(subtask); total += calculateLeafTime(subtask);
@@ -39,16 +40,17 @@ export function calculateLeafTime(task) {
} }
// Calculate sum of all LEAF descendant estimates (flat task list) // Calculate sum of all LEAF descendant estimates (flat task list)
// Excludes tasks marked as "done"
export function calculateLeafTimeFlat(task, allTasks) { export function calculateLeafTimeFlat(task, allTasks) {
// Find direct children // Find direct children
const children = allTasks.filter(t => t.parent_task_id === task.id); const children = allTasks.filter(t => t.parent_task_id === task.id);
// If no children, this is a leaf - return its own estimate // If no children, this is a leaf - return its own estimate if not done
if (children.length === 0) { if (children.length === 0) {
return task.estimated_minutes || 0; return (task.status !== 'done' && task.estimated_minutes) ? task.estimated_minutes : 0;
} }
// Has children, so sum up all leaf descendants // Has children, so sum up all leaf descendants (excluding done tasks)
let total = 0; let total = 0;
for (const child of children) { for (const child of children) {
total += calculateLeafTimeFlat(child, allTasks); total += calculateLeafTimeFlat(child, allTasks);