diff --git a/apps/ui/src/components/views/board-view/components/kanban-card/card-actions.tsx b/apps/ui/src/components/views/board-view/components/kanban-card/card-actions.tsx index b791216b..c22bc2bd 100644 --- a/apps/ui/src/components/views/board-view/components/kanban-card/card-actions.tsx +++ b/apps/ui/src/components/views/board-view/components/kanban-card/card-actions.tsx @@ -30,6 +30,29 @@ interface CardActionsProps { onApprovePlan?: () => void; } +/** + * Render contextual action buttons for a feature row based on the feature's status and whether it is the current automated task. + * + * Renders an appropriate set of buttons (Approve Plan, Logs, Force Stop, Verify, Resume, Complete, Edit, View Plan, Make, Refine, etc.) depending on + * feature properties (status, planSpec, skipTests, prUrl, id), the isCurrentAutoTask flag, and which callback props are provided. + * + * @param feature - The feature object whose status and metadata determine which actions are shown. + * @param isCurrentAutoTask - When true, renders actions relevant to the currently running automated task. + * @param hasContext - If true, indicates the feature has surrounding context (affects layout/availability in some states). + * @param shortcutKey - Optional keyboard shortcut label shown next to the Logs button when present. + * @param onEdit - Invoked when the Edit button is clicked. + * @param onViewOutput - Invoked when a Logs/View Output button is clicked. + * @param onVerify - Invoked when the Verify button (verification pathway) is clicked. + * @param onResume - Invoked when the Resume button is clicked. + * @param onForceStop - Invoked when the Force Stop button is clicked. + * @param onManualVerify - Invoked when a manual verification button is clicked. + * @param onFollowUp - Invoked when the Refine/Follow-up button is clicked. + * @param onImplement - Invoked when the Make/Implement button is clicked. + * @param onComplete - Invoked when the Complete button is clicked. + * @param onViewPlan - Invoked when the View Plan button is clicked. + * @param onApprovePlan - Invoked when the Approve Plan button is clicked. + * @returns The JSX element containing the action buttons for the feature row. + */ export function CardActions({ feature, isCurrentAutoTask, @@ -109,73 +132,90 @@ export function CardActions({ )} )} - {!isCurrentAutoTask && feature.status === 'in_progress' && ( - <> - {/* Approve Plan button - shows when plan is generated and waiting for approval */} - {feature.planSpec?.status === 'generated' && onApprovePlan && ( - - )} - {feature.skipTests && onManualVerify ? ( - - ) : onResume ? ( - - ) : null} - {onViewOutput && !feature.skipTests && ( - - )} - - )} + {!isCurrentAutoTask && + (feature.status === 'in_progress' || + (typeof feature.status === 'string' && feature.status.startsWith('pipeline_'))) && ( + <> + {/* Approve Plan button - shows when plan is generated and waiting for approval */} + {feature.planSpec?.status === 'generated' && onApprovePlan && ( + + )} + {feature.skipTests && onManualVerify ? ( + + ) : onResume ? ( + + ) : onVerify ? ( + + ) : null} + {onViewOutput && !feature.skipTests && ( + + )} + + )} {!isCurrentAutoTask && feature.status === 'verified' && ( <> {/* Logs button */} @@ -319,4 +359,4 @@ export function CardActions({ )} ); -} +} \ No newline at end of file diff --git a/apps/ui/src/components/views/board-view/hooks/use-board-effects.ts b/apps/ui/src/components/views/board-view/hooks/use-board-effects.ts index 318b326b..6bb93977 100644 --- a/apps/ui/src/components/views/board-view/hooks/use-board-effects.ts +++ b/apps/ui/src/components/views/board-view/hooks/use-board-effects.ts @@ -16,6 +16,23 @@ interface UseBoardEffectsProps { setFeaturesWithContext: (set: Set) => void; } +/** + * Registers and manages side effects for the board view (IPC/event listeners, global exposure, and context checks). + * + * Sets up event subscriptions to suggestions, spec regeneration, and auto-mode events; exposes the current project globally for modals; syncs running tasks from the backend; and maintains the set of feature IDs that have associated context files. + * + * @param currentProject - The active project object or `null`. Exposed globally for modal use and used when syncing backend state. + * @param specCreatingForProject - Project path currently undergoing spec regeneration, or `null`. + * @param setSpecCreatingForProject - Setter to clear or set the spec-regenerating project path. + * @param setSuggestionsCount - Setter for the persisted number of suggestion items. + * @param setFeatureSuggestions - Setter for the latest suggestion payload. + * @param setIsGeneratingSuggestions - Setter to mark whether suggestions are being generated. + * @param checkContextExists - Async function that returns whether a given feature ID has context files. + * @param features - Array of feature records to evaluate for potential context files. + * @param isLoading - Flag indicating whether features are still loading; context checks run only when loading is complete. + * @param featuresWithContext - Set of feature IDs currently known to have context files. + * @param setFeaturesWithContext - Setter that replaces the set of feature IDs that have context files. + */ export function useBoardEffects({ currentProject, specCreatingForProject, @@ -130,7 +147,10 @@ export function useBoardEffects({ const checkAllContexts = async () => { const featuresWithPotentialContext = features.filter( (f) => - f.status === 'in_progress' || f.status === 'waiting_approval' || f.status === 'verified' + f.status === 'in_progress' || + f.status === 'waiting_approval' || + f.status === 'verified' || + (typeof f.status === 'string' && f.status.startsWith('pipeline_')) ); const contextChecks = await Promise.all( featuresWithPotentialContext.map(async (f) => ({ @@ -179,4 +199,4 @@ export function useBoardEffects({ unsubscribe(); }; }, [checkContextExists, setFeaturesWithContext]); -} +} \ No newline at end of file