From cd122913ceaa50c0c7d94def83756f322eac95b5 Mon Sep 17 00:00:00 2001 From: Haileyesus Date: Mon, 2 Mar 2026 17:55:57 +0300 Subject: [PATCH] refactor(task-master): migrate tasks to a typed feature module - introduce a new feature-oriented TaskMaster domain under src/components/task-master - add typed TaskMaster context/provider with explicit project, task, MCP, and loading state handling - split task UI into focused components (panel, board, toolbar, content, card, detail modal, setup/help modals, banner) - move task board filtering/sorting/kanban derivation into dedicated hooks and utilities - relocate CreateTaskModal into the feature module and keep task views modular/readable - remove legacy monolithic TaskList/TaskDetail/TaskCard files and route main task panel to the new feature panel - replace contexts/TaskMasterContext.jsx with a typed contexts/TaskMasterContext.ts re-export to the feature context - update MainContent project sync logic to compare by project name to avoid state churn - validation: npm run typecheck, npm run build --- src/components/NextTaskBanner.jsx | 696 +---------- src/components/TaskCard.jsx | 210 ---- src/components/TaskDetail.jsx | 406 ------- src/components/TaskList.jsx | 1055 ----------------- .../main-content/view/MainContent.tsx | 7 +- .../view/subcomponents/TaskMasterPanel.tsx | 207 +--- .../task-master/context/TaskMasterContext.tsx | 279 +++++ .../task-master/hooks/useProjectPrdFiles.ts | 64 + .../task-master/hooks/useTaskBoardState.ts | 97 ++ src/components/task-master/index.ts | 4 + src/components/task-master/types.ts | 128 ++ .../task-master/utils/taskKanban.ts | 72 ++ .../task-master/utils/taskSorting.ts | 100 ++ .../task-master/view/NextTaskBanner.tsx | 213 ++++ src/components/task-master/view/TaskBoard.tsx | 199 ++++ .../task-master/view/TaskBoardContent.tsx | 124 ++ .../task-master/view/TaskBoardToolbar.tsx | 266 +++++ src/components/task-master/view/TaskCard.tsx | 210 ++++ .../task-master/view/TaskDetailModal.tsx | 318 +++++ .../task-master/view/TaskEmptyState.tsx | 134 +++ .../task-master/view/TaskMasterPanel.tsx | 150 +++ .../view/modals/CreateTaskModal.tsx} | 61 +- .../task-master/view/modals/TaskHelpModal.tsx | 129 ++ .../view/modals/TaskMasterSetupModal.tsx | 102 ++ .../view/shared/TaskFiltersPanel.tsx | 108 ++ .../view/shared/TaskQuickSortBar.tsx | 62 + src/contexts/TaskMasterContext.jsx | 301 ----- src/contexts/TaskMasterContext.ts | 6 + 28 files changed, 2796 insertions(+), 2912 deletions(-) delete mode 100644 src/components/TaskCard.jsx delete mode 100644 src/components/TaskDetail.jsx delete mode 100644 src/components/TaskList.jsx create mode 100644 src/components/task-master/context/TaskMasterContext.tsx create mode 100644 src/components/task-master/hooks/useProjectPrdFiles.ts create mode 100644 src/components/task-master/hooks/useTaskBoardState.ts create mode 100644 src/components/task-master/index.ts create mode 100644 src/components/task-master/types.ts create mode 100644 src/components/task-master/utils/taskKanban.ts create mode 100644 src/components/task-master/utils/taskSorting.ts create mode 100644 src/components/task-master/view/NextTaskBanner.tsx create mode 100644 src/components/task-master/view/TaskBoard.tsx create mode 100644 src/components/task-master/view/TaskBoardContent.tsx create mode 100644 src/components/task-master/view/TaskBoardToolbar.tsx create mode 100644 src/components/task-master/view/TaskCard.tsx create mode 100644 src/components/task-master/view/TaskDetailModal.tsx create mode 100644 src/components/task-master/view/TaskEmptyState.tsx create mode 100644 src/components/task-master/view/TaskMasterPanel.tsx rename src/components/{CreateTaskModal.jsx => task-master/view/modals/CreateTaskModal.tsx} (57%) create mode 100644 src/components/task-master/view/modals/TaskHelpModal.tsx create mode 100644 src/components/task-master/view/modals/TaskMasterSetupModal.tsx create mode 100644 src/components/task-master/view/shared/TaskFiltersPanel.tsx create mode 100644 src/components/task-master/view/shared/TaskQuickSortBar.tsx delete mode 100644 src/contexts/TaskMasterContext.jsx create mode 100644 src/contexts/TaskMasterContext.ts diff --git a/src/components/NextTaskBanner.jsx b/src/components/NextTaskBanner.jsx index 49eb941e..12c4ac47 100644 --- a/src/components/NextTaskBanner.jsx +++ b/src/components/NextTaskBanner.jsx @@ -1,695 +1,3 @@ -import React, { useState } from 'react'; -import { ArrowRight, List, Clock, Flag, CheckCircle, Circle, AlertCircle, Pause, ChevronDown, ChevronUp, Plus, FileText, Settings, X, Terminal, Eye, Play, Zap, Target } from 'lucide-react'; -import { cn } from '../lib/utils'; -import { useTaskMaster } from '../contexts/TaskMasterContext'; -import { api } from '../utils/api'; -import Shell from './shell/view/Shell'; -import TaskDetail from './TaskDetail'; +import NextTaskBanner from './task-master/view/NextTaskBanner'; -const NextTaskBanner = ({ onShowAllTasks, onStartTask, className = '' }) => { - const { nextTask, tasks, currentProject, isLoadingTasks, projectTaskMaster, refreshTasks, refreshProjects } = useTaskMaster(); - const [showDetails, setShowDetails] = useState(false); - const [showTaskOptions, setShowTaskOptions] = useState(false); - const [showCreateTaskModal, setShowCreateTaskModal] = useState(false); - const [showTemplateSelector, setShowTemplateSelector] = useState(false); - const [showCLI, setShowCLI] = useState(false); - const [showTaskDetail, setShowTaskDetail] = useState(false); - const [isLoading, setIsLoading] = useState(false); - - // Handler functions - const handleInitializeTaskMaster = async () => { - if (!currentProject) return; - - setIsLoading(true); - try { - const response = await api.taskmaster.init(currentProject.name); - if (response.ok) { - await refreshProjects(); - setShowTaskOptions(false); - } else { - const error = await response.json(); - console.error('Failed to initialize TaskMaster:', error); - alert(`Failed to initialize TaskMaster: ${error.message}`); - } - } catch (error) { - console.error('Error initializing TaskMaster:', error); - alert('Error initializing TaskMaster. Please try again.'); - } finally { - setIsLoading(false); - } - }; - - const handleCreateManualTask = () => { - setShowCreateTaskModal(true); - setShowTaskOptions(false); - }; - - const handleParsePRD = () => { - setShowTemplateSelector(true); - setShowTaskOptions(false); - }; - - // Don't show if no project or still loading - if (!currentProject || isLoadingTasks) { - return null; - } - - let bannerContent; - - // Show setup message only if no tasks exist AND TaskMaster is not configured - if ((!tasks || tasks.length === 0) && !projectTaskMaster?.hasTaskmaster) { - bannerContent = ( -
-
-
- -
-
- TaskMaster AI is not configured -
-
-
-
-
-
- -
-
- - {showTaskOptions && ( -
- {!projectTaskMaster?.hasTaskmaster && ( -
-

- 🎯 What is TaskMaster? -

-
-

• AI-Powered Task Management: Break complex projects into manageable subtasks

-

• PRD Templates: Generate tasks from Product Requirements Documents

-

• Dependency Tracking: Understand task relationships and execution order

-

• Progress Visualization: Kanban boards and detailed task analytics

-

• CLI Integration: Use taskmaster commands for advanced workflows

-
-
- )} -
- {!projectTaskMaster?.hasTaskmaster ? ( - - ) : ( - <> -
- Add more tasks: Create additional tasks manually or generate them from a PRD template -
- - - - )} -
-
- )} -
- ); - } else if (nextTask) { - // Show next task if available - bannerContent = ( -
-
-
-
-
- -
- Task {nextTask.id} - {nextTask.priority === 'high' && ( -
- -
- )} - {nextTask.priority === 'medium' && ( -
- -
- )} - {nextTask.priority === 'low' && ( -
- -
- )} -
-

- {nextTask.title} -

-
- -
- - - {onShowAllTasks && ( - - )} -
-
- -
- ); - } else if (tasks && tasks.length > 0) { - // Show completion message only if there are tasks and all are done - const completedTasks = tasks.filter(task => task.status === 'done').length; - const totalTasks = tasks.length; - - bannerContent = ( -
-
-
- - - {completedTasks === totalTasks ? "All done! 🎉" : "No pending tasks"} - -
-
- - {completedTasks}/{totalTasks} - - -
-
-
- ); - } else { - // TaskMaster is configured but no tasks exist - don't show anything in chat - bannerContent = null; - } - - return ( - <> - {bannerContent} - - {/* Create Task Modal */} - {showCreateTaskModal && ( - setShowCreateTaskModal(false)} - onTaskCreated={() => { - refreshTasks(); - setShowCreateTaskModal(false); - }} - /> - )} - - {/* Template Selector Modal */} - {showTemplateSelector && ( - setShowTemplateSelector(false)} - onTemplateApplied={() => { - refreshTasks(); - setShowTemplateSelector(false); - }} - /> - )} - - {/* TaskMaster CLI Setup Modal */} - {showCLI && ( -
-
- {/* Modal Header */} -
-
-
- -
-
-

TaskMaster Setup

-

Interactive CLI for {currentProject?.displayName}

-
-
- -
- - {/* Terminal Container */} -
-
- -
-
- - {/* Modal Footer */} -
-
-
- TaskMaster initialization will start automatically -
- -
-
-
-
- )} - - {/* Task Detail Modal */} - {showTaskDetail && nextTask && ( - setShowTaskDetail(false)} - onStatusChange={() => refreshTasks?.()} - onTaskClick={null} // Disable dependency navigation in NextTaskBanner for now - /> - )} - - ); -}; - -// Simple Create Task Modal Component -const CreateTaskModal = ({ currentProject, onClose, onTaskCreated }) => { - const [formData, setFormData] = useState({ - title: '', - description: '', - priority: 'medium', - useAI: false, - prompt: '' - }); - const [isSubmitting, setIsSubmitting] = useState(false); - - const handleSubmit = async (e) => { - e.preventDefault(); - if (!currentProject) return; - - setIsSubmitting(true); - try { - const taskData = formData.useAI - ? { prompt: formData.prompt, priority: formData.priority } - : { title: formData.title, description: formData.description, priority: formData.priority }; - - const response = await api.taskmaster.addTask(currentProject.name, taskData); - - if (response.ok) { - onTaskCreated(); - } else { - const error = await response.json(); - console.error('Failed to create task:', error); - alert(`Failed to create task: ${error.message}`); - } - } catch (error) { - console.error('Error creating task:', error); - alert('Error creating task. Please try again.'); - } finally { - setIsSubmitting(false); - } - }; - - return ( -
-
-
-

Create New Task

- -
- -
-
- -
- - {formData.useAI ? ( -
- -