From 8000a464c9b75e2371357bcd875795f4a5cb03dd Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 20 Nov 2025 16:13:00 +0000 Subject: [PATCH] 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. --- CHANGELOG.md | 157 +++++++++++++++++++++++++ README.md | Bin 7337 -> 11146 bytes backend/app/crud.py | 38 ++++++ frontend/src/App.jsx | 2 +- frontend/src/components/KanbanView.jsx | 2 +- frontend/src/components/TreeView.jsx | 2 +- 6 files changed, 198 insertions(+), 3 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..2e0f29a --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,157 @@ +# Changelog + +All notable changes to TESSERACT will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.1.4] - 2025-01-XX + +### Added +- Strikethrough styling for time estimates when tasks are marked as "done" +- Auto-complete parent tasks when all child tasks are marked as "done" + - Works recursively up the task hierarchy + - Parents automatically transition to "done" status when all children complete + +### Changed +- Time estimates on completed tasks now display with strikethrough decoration +- Parent task status automatically updates based on children completion state + +## [0.1.3] - 2025-01-XX + +### Added +- Enhanced task creation forms with metadata fields + - Title field (required) + - Tags field (comma-separated input) + - Time estimate fields (hours and minutes) + - Flag color selector with 8 color options +- TaskForm component for consistent task creation across views +- Status change dropdown in TaskMenu (no longer requires Kanban view) +- Leaf-based time calculation system + - Parent tasks show sum of descendant leaf task estimates + - Prevents double-counting when both parents and children have estimates + - Excludes "done" tasks from time calculations +- Time format changed from decimal hours to hours + minutes (e.g., "1h 30m" instead of "1.5h") +- CHANGELOG.md and README.md documentation + +### Changed +- Task creation now includes all metadata fields upfront +- Time estimates display remaining work (excludes completed tasks) +- Time input uses separate hours/minutes fields instead of single minutes field +- Parent task estimates calculated from leaf descendants only + +### Fixed +- Time calculation now accurately represents remaining work +- Time format more human-readable with hours and minutes + +## [0.1.2] - 2025-01-XX + +### Added +- Metadata fields for tasks: + - `estimated_minutes` (Integer) - Time estimate stored in minutes + - `tags` (JSON Array) - Categorization tags + - `flag_color` (String) - Priority flag with 7 color options +- TaskMenu component with three-dot dropdown + - Edit time estimates + - Edit tags (comma-separated) + - Set flag colors + - Edit task title + - Delete tasks +- SearchBar component in header + - Real-time search with 300ms debounce + - Optional project filtering + - Click results to navigate to project + - Displays metadata in results +- Time and tag display in TreeView and KanbanView +- Flag color indicators on tasks +- Backend search endpoint `/api/search` with project filtering + +### Changed +- TreeView and KanbanView now display task metadata +- Enhanced visual design with metadata badges + +## [0.1.1] - 2025-01-XX + +### Fixed +- Tree view indentation now scales properly with nesting depth + - Changed from fixed `ml-6` to calculated `marginLeft: ${level * 1.5}rem` + - Each nesting level adds 1.5rem (24px) of indentation +- Kanban view subtask handling + - All tasks (including subtasks) now appear as individual draggable cards + - Subtasks show parent context: "↳ subtask of: [parent name]" + - Removed nested subtask list display + +### Changed +- Improved visual hierarchy in tree view +- Better subtask representation in Kanban board + +## [0.1.0] - 2025-01-XX + +### Added +- Initial MVP release +- Core Features: + - Arbitrary-depth nested task hierarchies + - Two view modes: Tree View and Kanban Board + - Self-hosted architecture with Docker deployment + - JSON import for LLM-generated task trees +- Technology Stack: + - Backend: Python FastAPI with SQLAlchemy ORM + - Database: SQLite with self-referencing Task model + - Frontend: React + Tailwind CSS + - Deployment: Docker with nginx reverse proxy +- Project Management: + - Create/read/update/delete projects + - Project-specific task trees +- Task Management: + - Create tasks with title, description, status + - Four status types: Backlog, In Progress, Blocked, Done + - Hierarchical task nesting (task → subtask → sub-subtask → ...) + - Add subtasks to any task + - Delete tasks (cascading to all subtasks) +- Tree View: + - Collapsible hierarchical display + - Expand/collapse subtasks + - Visual nesting indentation + - Inline editing + - Status display +- Kanban Board: + - Four columns: Backlog, In Progress, Blocked, Done + - Drag-and-drop to change status + - All tasks shown as cards (including subtasks) +- JSON Import: + - Bulk import task trees from JSON files + - Supports arbitrary nesting depth + - Example import file included +- UI/UX: + - Dark cyberpunk theme + - Orange (#ff6b35) accent color + - Responsive design + - Real-time updates + +### Technical Details +- Backend API endpoints: + - `/api/projects` - Project CRUD + - `/api/tasks` - Task CRUD + - `/api/projects/{id}/tree` - Hierarchical task tree + - `/api/projects/{id}/tasks` - Flat task list + - `/api/projects/{id}/import` - JSON import +- Database Schema: + - `projects` table with id, name, description + - `tasks` table with self-referencing `parent_task_id` +- Frontend Routing: + - `/` - Project list + - `/project/:id` - Project view with Tree/Kanban toggle +- Docker Setup: + - Multi-stage builds for optimization + - Nginx reverse proxy configuration + - Named volumes for database persistence + - Development and production configurations + +## Project Information + +**TESSERACT** - Task Decomposition Engine +A self-hosted web application for managing deeply nested todo trees with advanced time tracking and project planning capabilities. + +**Repository**: https://github.com/serversdwn/tesseract +**License**: MIT +**Author**: serversdwn diff --git a/README.md b/README.md index 8907cf24d7ca26e3c46a4f7ee15b22e0ee74c6ce..811b11c89259cbd66652db57efb17b6e357e4bce 100644 GIT binary patch literal 11146 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 literal 7337 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 OJ@{m(3PhLsWAb0zp`$AR diff --git a/backend/app/crud.py b/backend/app/crud.py index db0f379..17b7924 100644 --- a/backend/app/crud.py +++ b/backend/app/crud.py @@ -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 diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index e01dc41..175785c 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -13,7 +13,7 @@ function App() {

TESSERACT Task Decomposition Engine - v0.1.3 + v0.1.4

diff --git a/frontend/src/components/KanbanView.jsx b/frontend/src/components/KanbanView.jsx index 6474978..43327bb 100644 --- a/frontend/src/components/KanbanView.jsx +++ b/frontend/src/components/KanbanView.jsx @@ -111,7 +111,7 @@ function TaskCard({ task, allTasks, onUpdate, onDragStart }) {
{/* Time estimate */} {formatTimeWithTotal(task, allTasks) && ( -
+
{formatTimeWithTotal(task, allTasks)}
diff --git a/frontend/src/components/TreeView.jsx b/frontend/src/components/TreeView.jsx index f9c9de1..7a3a2ce 100644 --- a/frontend/src/components/TreeView.jsx +++ b/frontend/src/components/TreeView.jsx @@ -166,7 +166,7 @@ function TaskNode({ task, projectId, onUpdate, level = 0 }) {
{/* Time estimate */} {formatTimeWithTotal(task) && ( -
+
{formatTimeWithTotal(task)}