Release v0.1.4: Auto-complete parents and done task strikethrough

New Features:
1. Auto-Complete Parent Tasks
   - When all child tasks are marked as "done", parent automatically becomes "done"
   - Works recursively up the task hierarchy
   - Implemented in backend crud.py with check_and_update_parent_status()
   - Prevents manual status management for completed branches

2. Strikethrough for Done Tasks
   - Time estimates crossed out when task status is "done"
   - Visual indicator that work is completed
   - Applied in both TreeView and KanbanView

3. Updated Version
   - Bumped to v0.1.4 in App.jsx header

4. Documentation
   - Added comprehensive CHANGELOG.md
   - Updated README.md with v0.1.4 features
   - Documented all versions from v0.1.0 to v0.1.4
   - Added usage examples, architecture diagrams, troubleshooting

Technical Changes:
- backend/app/crud.py: Added check_and_update_parent_status() recursive function
- frontend/src/components/TreeView.jsx: Added line-through styling for done tasks
- frontend/src/components/KanbanView.jsx: Added line-through styling for done tasks
- frontend/src/App.jsx: Version updated to v0.1.4

This release completes the intelligent time tracking and auto-completion features,
making TESSERACT a fully-featured hierarchical task management system.
This commit is contained in:
Claude
2025-11-20 16:13:00 +00:00
parent 718e5acbe2
commit 8000a464c9
6 changed files with 198 additions and 3 deletions

View File

@@ -92,6 +92,32 @@ def get_task_with_subtasks(db: Session, task_id: int) -> Optional[models.Task]:
).filter(models.Task.id == task_id).first()
def check_and_update_parent_status(db: Session, parent_id: int):
"""Check if all children of a parent are done, and mark parent as done if so"""
# Get all children of this parent
children = db.query(models.Task).filter(
models.Task.parent_task_id == parent_id
).all()
# If no children, nothing to do
if not children:
return
# Check if all children are done
all_done = all(child.status == models.TaskStatus.DONE for child in children)
if all_done:
# Mark parent as done
parent = get_task(db, parent_id)
if parent and parent.status != models.TaskStatus.DONE:
parent.status = models.TaskStatus.DONE
db.commit()
# Recursively check grandparent
if parent.parent_task_id:
check_and_update_parent_status(db, parent.parent_task_id)
def update_task(
db: Session, task_id: int, task: schemas.TaskUpdate
) -> Optional[models.Task]:
@@ -100,11 +126,23 @@ def update_task(
return None
update_data = task.model_dump(exclude_unset=True)
status_changed = False
# Check if status is being updated
if "status" in update_data:
status_changed = True
old_status = db_task.status
for key, value in update_data.items():
setattr(db_task, key, value)
db.commit()
db.refresh(db_task)
# If status changed to 'done' and this task has a parent, check if parent should auto-complete
if status_changed and db_task.status == models.TaskStatus.DONE and db_task.parent_task_id:
check_and_update_parent_status(db, db_task.parent_task_id)
return db_task