diff --git a/src/frontend/index.html b/src/frontend/index.html index 16d5b6dc7..3f9c02611 100644 --- a/src/frontend/index.html +++ b/src/frontend/index.html @@ -10,7 +10,7 @@ content="MACAE - Multi-Agent Custom Automation Engine" /> - + Multi-Agent - Custom Automation Engine diff --git a/src/frontend/src/api/apiService.tsx b/src/frontend/src/api/apiService.tsx index 9367b1fec..1b11ab621 100644 --- a/src/frontend/src/api/apiService.tsx +++ b/src/frontend/src/api/apiService.tsx @@ -160,7 +160,7 @@ export class APIService { if (useCache) { const cachedPlan = this._cache.get<{ plan_with_steps: PlanWithSteps; messages: PlanMessage[] }>(cacheKey); - //if (cachedPlan) return cachedPlan; + if (cachedPlan) return cachedPlan; return this._requestTracker.trackRequest(cacheKey, fetcher); } diff --git a/src/frontend/src/components/content/TaskDetails.tsx b/src/frontend/src/components/content/TaskDetails.tsx index 9026339c3..142bec13a 100644 --- a/src/frontend/src/components/content/TaskDetails.tsx +++ b/src/frontend/src/components/content/TaskDetails.tsx @@ -118,7 +118,13 @@ const TaskDetails: React.FC = ({
- {planData.plan.initial_goal} + + + {planData.plan.initial_goal} + +
{completedCount} of {total} completed diff --git a/src/frontend/src/components/content/TaskList.tsx b/src/frontend/src/components/content/TaskList.tsx index a4c8afac1..a998b7768 100644 --- a/src/frontend/src/components/content/TaskList.tsx +++ b/src/frontend/src/components/content/TaskList.tsx @@ -45,11 +45,12 @@ const TaskList: React.FC = ({
{task.name}
- - - {task.date && ( + {task.date && task.status == "completed" &&( {task.date} )} + {task.status == "inprogress" &&( + {`${task?.completed_steps} of ${task?.total_steps} completed`} + )}
diff --git a/src/frontend/src/models/taskList.tsx b/src/frontend/src/models/taskList.tsx index ee65bb991..d99f8c9bd 100644 --- a/src/frontend/src/models/taskList.tsx +++ b/src/frontend/src/models/taskList.tsx @@ -3,6 +3,8 @@ export interface Task { name: string; status: 'inprogress' | 'completed'; date?: string; + completed_steps?: number; + total_steps?: number; } export interface TaskListProps { diff --git a/src/frontend/src/pages/PlanPage.tsx b/src/frontend/src/pages/PlanPage.tsx index 43934daf3..7ec500d15 100644 --- a/src/frontend/src/pages/PlanPage.tsx +++ b/src/frontend/src/pages/PlanPage.tsx @@ -69,7 +69,7 @@ const PlanPage: React.FC = () => { } setError(null); - const data = await PlanDataService.fetchPlanData(planId); + const data = await PlanDataService.fetchPlanData(planId,navigate); console.log("Fetched plan data:", data); setPlanData(data); } catch (err) { @@ -146,7 +146,7 @@ const PlanPage: React.FC = () => { useEffect(() => { - loadPlanData(); + loadPlanData(true); }, [loadPlanData]); const handleNewTaskButton = () => { diff --git a/src/frontend/src/services/PlanDataService.tsx b/src/frontend/src/services/PlanDataService.tsx index de56c5559..9196459e7 100644 --- a/src/frontend/src/services/PlanDataService.tsx +++ b/src/frontend/src/services/PlanDataService.tsx @@ -1,135 +1,160 @@ -import { PlanWithSteps, Step, AgentType, ProcessedPlanData, PlanMessage } from '@/models'; -import { apiService } from '@/api'; - +import { + PlanWithSteps, + Step, + AgentType, + ProcessedPlanData, + PlanMessage, +} from "@/models"; +import { apiService } from "@/api"; /** * Service for processing and managing plan data operations */ -export class PlanDataService { /** - * Fetch plan details by plan ID and process the data - * @param planId Plan ID to fetch - * @returns Promise with processed plan data - */ - static async fetchPlanData(planId: string): Promise { - try { - // Use optimized getPlanById method for better performance - const planBody = await apiService.getPlanById(planId); - return this.processPlanData(planBody.plan_with_steps, planBody.messages || []); - } catch (error) { - console.log('Failed to fetch plan data:', error); - throw error; - } +export class PlanDataService { + /** + * Fetch plan details by plan ID and process the data + * @param planId Plan ID to fetch + * @returns Promise with processed plan data + */ + static async fetchPlanData( + planId: string, + useCache: boolean + ): Promise { + try { + // Use optimized getPlanById method for better performance + const planBody = await apiService.getPlanById(planId, useCache); + return this.processPlanData( + planBody.plan_with_steps, + planBody.messages || [] + ); + } catch (error) { + console.log("Failed to fetch plan data:", error); + throw error; } + } - /** - * Process plan data to extract agents, steps, and clarification status - * @param plan PlanWithSteps object to process - * @returns Processed plan data - */ - static processPlanData(plan: PlanWithSteps, messages: PlanMessage[]): ProcessedPlanData { - // Extract unique agents from steps - const uniqueAgents = new Set(); - plan.steps.forEach(step => { - if (step.agent) { - uniqueAgents.add(step.agent); - } - }); + /** + * Process plan data to extract agents, steps, and clarification status + * @param plan PlanWithSteps object to process + * @returns Processed plan data + */ + static processPlanData( + plan: PlanWithSteps, + messages: PlanMessage[] + ): ProcessedPlanData { + // Extract unique agents from steps + const uniqueAgents = new Set(); + plan.steps.forEach((step) => { + if (step.agent) { + uniqueAgents.add(step.agent); + } + }); - // Convert Set to Array for easier handling - const agents = Array.from(uniqueAgents); + // Convert Set to Array for easier handling + const agents = Array.from(uniqueAgents); - // Get all steps - const steps = plan.steps; + // Get all steps + const steps = plan.steps; - // Check if human_clarification_request is not null - const hasClarificationRequest = plan.human_clarification_request != null && plan.human_clarification_request.trim().length > 0; - const hasClarificationResponse = plan.human_clarification_response != null && plan.human_clarification_response.trim().length > 0; - const enableChat = hasClarificationRequest && !hasClarificationResponse; - const enableStepButtons = (hasClarificationRequest && hasClarificationResponse) || (!hasClarificationRequest && !hasClarificationResponse); - return { - plan, - agents, - steps, - hasClarificationRequest, - hasClarificationResponse, - enableChat, - enableStepButtons, - messages - }; - } + // Check if human_clarification_request is not null + const hasClarificationRequest = + plan.human_clarification_request != null && + plan.human_clarification_request.trim().length > 0; + const hasClarificationResponse = + plan.human_clarification_response != null && + plan.human_clarification_response.trim().length > 0; + const enableChat = hasClarificationRequest && !hasClarificationResponse; + const enableStepButtons = + (hasClarificationRequest && hasClarificationResponse) || + (!hasClarificationRequest && !hasClarificationResponse); + return { + plan, + agents, + steps, + hasClarificationRequest, + hasClarificationResponse, + enableChat, + enableStepButtons, + messages, + }; + } - /** - * Get steps for a specific agent type - * @param plan Plan with steps - * @param agentType Agent type to filter by - * @returns Array of steps for the specified agent - */ - static getStepsForAgent(plan: PlanWithSteps, agentType: AgentType): Step[] { - return apiService.getStepsForAgent(plan, agentType); - } + /** + * Get steps for a specific agent type + * @param plan Plan with steps + * @param agentType Agent type to filter by + * @returns Array of steps for the specified agent + */ + static getStepsForAgent(plan: PlanWithSteps, agentType: AgentType): Step[] { + return apiService.getStepsForAgent(plan, agentType); + } - /** - * Get steps that are awaiting human feedback - * @param plan Plan with steps - * @returns Array of steps awaiting feedback - */ - static getStepsAwaitingFeedback(plan: PlanWithSteps): Step[] { - return apiService.getStepsAwaitingFeedback(plan); - } + /** + * Get steps that are awaiting human feedback + * @param plan Plan with steps + * @returns Array of steps awaiting feedback + */ + static getStepsAwaitingFeedback(plan: PlanWithSteps): Step[] { + return apiService.getStepsAwaitingFeedback(plan); + } - /** - * Check if plan is complete - * @param plan Plan with steps - * @returns Boolean indicating if plan is complete - */ - static isPlanComplete(plan: PlanWithSteps): boolean { - return apiService.isPlanComplete(plan); - } + /** + * Check if plan is complete + * @param plan Plan with steps + * @returns Boolean indicating if plan is complete + */ + static isPlanComplete(plan: PlanWithSteps): boolean { + return apiService.isPlanComplete(plan); + } - /** - * Get plan completion percentage - * @param plan Plan with steps - * @returns Completion percentage (0-100) - */ - static getPlanCompletionPercentage(plan: PlanWithSteps): number { - return apiService.getPlanCompletionPercentage(plan); - } - - /** - * Approve a plan step - * @param step Step to approve - * @returns Promise with API response - */ - static async stepStatus(step: Step, action: boolean): Promise<{ status: string }> { - try { + /** + * Get plan completion percentage + * @param plan Plan with steps + * @returns Completion percentage (0-100) + */ + static getPlanCompletionPercentage(plan: PlanWithSteps): number { + return apiService.getPlanCompletionPercentage(plan); + } - - return apiService.stepStatus( - step.plan_id, - step.session_id, - action, // approved - step.id - ); - } catch (error) { - console.log('Failed to change step status:', error); - throw error; - } + /** + * Approve a plan step + * @param step Step to approve + * @returns Promise with API response + */ + static async stepStatus( + step: Step, + action: boolean + ): Promise<{ status: string }> { + try { + return apiService.stepStatus( + step.plan_id, + step.session_id, + action, // approved + step.id + ); + } catch (error) { + console.log("Failed to change step status:", error); + throw error; } + } - - /** - * Submit human clarification for a plan - * @param planId Plan ID - * @param sessionId Session ID - * @param clarification Clarification text - * @returns Promise with API response - */ - static async submitClarification(planId: string, sessionId: string, clarification: string) { - try { - return apiService.submitClarification(planId, sessionId, clarification); - } catch (error) { - console.log('Failed to submit clarification:', error); - throw error; - } + /** + * Submit human clarification for a plan + * @param planId Plan ID + * @param sessionId Session ID + * @param clarification Clarification text + * @returns Promise with API response + */ + static async submitClarification( + planId: string, + sessionId: string, + clarification: string + ) { + try { + return apiService.submitClarification(planId, sessionId, clarification); + } catch (error) { + console.log("Failed to submit clarification:", error); + throw error; } + } } diff --git a/src/frontend/src/services/TaskService.tsx b/src/frontend/src/services/TaskService.tsx index 76bfd3c0c..7520b50ec 100644 --- a/src/frontend/src/services/TaskService.tsx +++ b/src/frontend/src/services/TaskService.tsx @@ -24,6 +24,8 @@ export class TaskService { const task: Task = { id: plan.session_id, name: plan.initial_goal, + completed_steps: plan.completed, + total_steps: plan.total_steps, status: apiService.isPlanComplete(plan) ? 'completed' : 'inprogress', date: new Date(plan.timestamp).toLocaleDateString('en-US', { month: 'short', diff --git a/src/frontend/src/styles/TaskDetails.css b/src/frontend/src/styles/TaskDetails.css index 5e40f1250..6c622c417 100644 --- a/src/frontend/src/styles/TaskDetails.css +++ b/src/frontend/src/styles/TaskDetails.css @@ -146,4 +146,14 @@ } .strikethrough { text-decoration: line-through; +} + +.goal-text { + display: -webkit-box !important; + -webkit-line-clamp: 2 !important; + -webkit-box-orient: vertical !important; + overflow: hidden !important; + text-overflow: ellipsis !important; + white-space: normal !important; + max-width: 300px; } \ No newline at end of file