Skip to content

fix(ui): make TaskStats phase-aware to fix late-joining user bug - #234

Merged
frankbria merged 1 commit into
mainfrom
fix/taskstats-planning-phase-awareness
Jan 9, 2026
Merged

fix(ui): make TaskStats phase-aware to fix late-joining user bug#234
frankbria merged 1 commit into
mainfrom
fix/taskstats-planning-phase-awareness

Conversation

@frankbria

@frankbria frankbria commented Jan 9, 2026

Copy link
Copy Markdown
Owner

Summary

  • Fixes the "late-joining user" bug where TaskStats showed 0 tasks during planning phase
  • TaskStats now correctly uses issuesData (REST API) during planning phase instead of agent state (WebSocket)
  • Adds phase-aware data source selection pattern for future component updates

Problem

When a user views the Dashboard during the planning phase, the Tasks tab badge showed "Review (24)" (from issuesData API), but TaskStats showed 0 for all counts (from empty agent state). This inconsistency confused users about the actual number of tasks.

Root Cause

TaskStats used useAgentState() hook exclusively, which only has data during development when agents are actively working. During planning phase, agent state is empty but tasks exist in the issues API.

Solution

Made TaskStats phase-aware:

  1. Added phase and issuesData props
  2. When phase === 'planning': Calculate stats from issuesData
  3. When phase === 'development' or 'review': Use useAgentState() (existing behavior)
  4. Maintains backward compatibility (props are optional)

Changes

File Changes
TaskStats.tsx Added props interface, calculateStatsFromIssues helper, phase-aware logic
Dashboard.tsx Pass phase and issuesData props to TaskStats
TaskStats.test.tsx Added 8 new tests for phase-aware behavior
code-review/ Added code review report

Test Plan

  • All 15 TaskStats tests pass
  • All 44 Dashboard tests pass
  • Full test suite (1498 tests) passes
  • TypeScript compilation clean
  • Code review completed (0 critical/major issues)

Manual Testing

  1. Create a new project and complete discovery
  2. Wait for task breakdown generation (planning phase)
  3. Verify TaskStats shows same count as tab badge "Review (N)"
  4. Approve tasks and verify TaskStats switches to agent state data

Related Issues

  • Creates technical debt issue codeframe-7pya documenting other at-risk components
  • Related to late-joining user E2E tests (commits cb408ed, e1539b8)

Summary by CodeRabbit

  • New Features

    • TaskStats component now intelligently selects data sources based on project phase—planning phase uses REST API data, while development and review phases use real-time state updates.
  • Documentation

    • Added comprehensive code-review documentation for phase-aware data source implementation.
  • Tests

    • Added extensive test coverage for phase-aware data source selection and edge cases.

✏️ Tip: You can customize this high-level summary in your review settings.

TaskStats now correctly displays task counts during planning phase by
using issuesData (REST API) instead of agent state (WebSocket) which
is empty until development begins.

Changes:
- Add phase and issuesData props to TaskStats component
- Implement conditional data source selection based on phase
- Add calculateStatsFromIssues helper for planning phase stats
- Update Dashboard to pass phase and issuesData to TaskStats
- Add 8 new tests for phase-aware behavior and edge cases

This fixes the bug where TaskStats showed 0 tasks during planning
phase even though the tab badge showed "Review (24)".

Related: codeframe-7pya (documents other at-risk components)
@coderabbitai

coderabbitai Bot commented Jan 9, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

The PR implements phase-aware data sourcing for TaskStats, where planning-phase views use REST API data while development/review phases use real-time WebSocket updates from useAgentState. TaskStats gains new props (phase, issuesData) with a conditional data-source selector and helper function. Dashboard is updated to pass these props. Comprehensive tests and code-review documentation accompany the implementation.

Changes

Cohort / File(s) Summary
Issue & Documentation
.beads/issues.jsonl, docs/code-review/2026-01-08-taskstats-phase-awareness-review.md
New phase-awareness audit issue tracked; comprehensive code-review report documents TaskStats changes, minor optimization suggestions (single-pass iteration), and production readiness with backward-compatibility assessment
Component Implementation
web-ui/src/components/tasks/TaskStats.tsx, web-ui/src/components/Dashboard.tsx
TaskStats now accepts phase and issuesData props; adds TaskStatsProps interface and calculateStatsFromIssues() helper; conditionally selects REST API data for planning phase or useAgentState for development/review phases; Dashboard updated to pass normalized phase and issuesData to TaskStats
Phase-Aware Data Source Tests
web-ui/__tests__/components/tasks/TaskStats.test.tsx
Comprehensive test suite verifying phase-aware data sourcing: planning phase REST data selection, development/review phase agent state precedence, backward compatibility, phase transitions, and edge cases (empty tasks, undefined state, total\_tasks consistency)

Sequence Diagram

sequenceDiagram
    participant Dashboard
    participant TaskStats
    participant DataSource as Data Source<br/>(Conditional)
    participant REST as REST API<br/>(issuesData)
    participant WS as WebSocket<br/>(useAgentState)

    Dashboard->>TaskStats: Render with phase & issuesData props
    TaskStats->>DataSource: Check phase
    
    alt Planning Phase
        DataSource->>REST: Fetch issuesData
        REST-->>DataSource: Return issues with tasks
        DataSource->>TaskStats: Provide stats from REST
    else Development/Review Phase
        DataSource->>WS: Use useAgentState hook
        WS-->>DataSource: Return agent state tasks
        DataSource->>TaskStats: Provide stats from agent state
    end
    
    TaskStats->>TaskStats: Memoize computed stats
    TaskStats-->>Dashboard: Render task counts
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Poem

🐰 Phase-aware whiskers twitch with glee,
Planning via REST, real-time through WebSocket spree!
TaskStats now knows which path to take,
Conditional sources for every phase's sake!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: making TaskStats phase-aware to fix a specific bug affecting late-joining users during planning phase.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/taskstats-planning-phase-awareness

Comment @coderabbitai help to get the list of available commands and usage tips.

@claude

claude Bot commented Jan 9, 2026

Copy link
Copy Markdown

Code Review: Phase-Aware TaskStats Implementation

I've reviewed PR #234 and the implementation looks excellent. This is a well-designed fix for the "late-joining user" bug with comprehensive test coverage and proper architectural considerations.

✅ Strengths

1. Solid React Best Practices

  • Proper hooks usage (unconditional call to useAgentState at TaskStats.tsx:87)
  • Comprehensive memoization with correct dependencies (TaskStats.tsx:99-112)
  • Backward compatibility maintained through optional props
  • React.memo export for performance optimization

2. Excellent Test Coverage
The 8 new tests in the "Phase-Aware Data Source Selection" suite cover all critical scenarios:

  • Planning phase using issuesData ✅
  • Development/review phases using agent state ✅
  • Missing issuesData handling ✅
  • Issues without tasks handling ✅
  • Phase transition behavior ✅
  • Backward compatibility ✅
  • API consistency verification (total_tasks matching) ✅

3. Defensive Programming

  • Optional chaining: issuesData?.issues (TaskStats.tsx:57)
  • Fallback to empty arrays: issue.tasks || [] (TaskStats.tsx:63)
  • Graceful degradation when data is undefined

4. Clear Documentation

  • JSDoc comments explaining the phase-aware approach
  • Test comments documenting the "late-joining user" scenario
  • Code review document tracking minor issues and future work

5. Architectural Thinking
Creating issue codeframe-7pya to track other at-risk components demonstrates good technical leadership. The pattern established here is reusable.

📝 Minor Observations (Non-blocking)

Performance Optimization Opportunity (TaskStats.tsx:67-70)
The calculateStatsFromIssues function filters the array 3 times. For large task lists, a single-pass approach would be more efficient:

// Current (3 passes)
return {
  total: allTasks.length,
  completed: allTasks.filter((t) => t.status === 'completed').length,
  blocked: allTasks.filter((t) => t.status === 'blocked').length,
  inProgress: allTasks.filter((t) => t.status === 'in_progress').length,
};

// Single-pass alternative
const counts = { total: allTasks.length, completed: 0, blocked: 0, inProgress: 0 };
for (const task of allTasks) {
  if (task.status === 'completed') counts.completed++;
  else if (task.status === 'blocked') counts.blocked++;
  else if (task.status === 'in_progress') counts.inProgress++;
}
return counts;

Assessment: Low priority - typical planning phase task counts are small (<100 tasks), and memoization ensures this runs infrequently. The current implementation is more readable. Acceptable as-is.

Type Safety Enhancement (TaskStats.tsx:37)
The phase prop uses string type rather than a union type:

// Current
phase?: string;

// More specific
phase?: 'discovery' | 'planning' | 'development' | 'review' | 'complete' | 'shipped';

Assessment: Low priority - the component only checks for 'planning' equality, so the string comparison works correctly. The broader type allows flexibility if phase names change. Acceptable as-is.

🎯 Consistency Check

The change in Dashboard.tsx:702 correctly passes both props:

<TaskStats phase={normalizePhase(projectData.phase)} issuesData={issuesData} />

This ensures TaskStats receives the normalized phase string and the issues data loaded from the REST API.

📊 Test Results

  • All 15 TaskStats tests passing ✅
  • All 44 Dashboard tests passing ✅
  • Full test suite: 1498 tests passing ✅
  • TypeScript compilation clean ✅

🔄 Future Considerations

The technical debt issue codeframe-7pya appropriately identifies other components that may need similar phase-awareness:

  • High Priority: AgentPanel, ProgressIndicator, TaskTreeView
  • Medium Priority: MetricsCharts, QualityGates

This demonstrates good system thinking about consistent data source selection across the application.

✅ Recommendation

APPROVE & MERGE - This PR is production-ready.

The implementation is clean, well-tested, and follows React best practices. The minor observations noted above are optimization opportunities, not functional issues. The comprehensive test suite and backward compatibility ensure this change is safe to deploy.

Great work on identifying the root cause (dual data systems) and implementing a pattern that can be applied to other components! 🎉

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
web-ui/src/components/tasks/TaskStats.tsx (1)

37-37: Consider using a union type for phase prop.

The phase prop is typed as string, but the component only checks for 'planning'. A union type would provide better type safety and IDE autocomplete:

phase?: 'discovery' | 'planning' | 'development' | 'review' | 'complete' | 'shipped';

This aligns with the normalizePhase function in Dashboard.tsx which defines these exact values.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cb408ed and 1de7063.

📒 Files selected for processing (5)
  • .beads/issues.jsonl
  • docs/code-review/2026-01-08-taskstats-phase-awareness-review.md
  • web-ui/__tests__/components/tasks/TaskStats.test.tsx
  • web-ui/src/components/Dashboard.tsx
  • web-ui/src/components/tasks/TaskStats.tsx
🧰 Additional context used
📓 Path-based instructions (5)
**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

Documentation files must be sized to fit in a single agent context window (spec.md ~200-400 lines, plan.md ~300-600 lines, tasks.md ~400-800 lines)

Files:

  • docs/code-review/2026-01-08-taskstats-phase-awareness-review.md
web-ui/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

web-ui/src/**/*.{ts,tsx}: Use TypeScript 5.3+ for frontend development with React 18, Next.js 14, Tailwind CSS, and Hugeicons for icons
Use TypeScript strict mode and ensure 100% type safety with no hardcoded types or any usage in frontend code

Files:

  • web-ui/src/components/Dashboard.tsx
  • web-ui/src/components/tasks/TaskStats.tsx
web-ui/src/components/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

web-ui/src/components/**/*.tsx: Use shadcn/ui Nova template components with semantic color palette (bg-card, text-foreground, etc.) and avoid hardcoded color values
Use cn() utility for conditional Tailwind CSS classes and follow Nova's compact spacing conventions

Files:

  • web-ui/src/components/Dashboard.tsx
  • web-ui/src/components/tasks/TaskStats.tsx
web-ui/src/**/*.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Replace all icon usage with Hugeicons (@hugeicons/react) and do not mix with lucide-react

Files:

  • web-ui/src/components/Dashboard.tsx
  • web-ui/src/components/tasks/TaskStats.tsx
web-ui/src/components/Dashboard.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Use React.memo on all Dashboard sub-components and useMemo for derived state to optimize performance with multi-agent support

Files:

  • web-ui/src/components/Dashboard.tsx
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T19:08:54.154Z
Learning: Applies to specs/*/tasks.md : Feature task files (tasks.md) must include phase-by-phase task breakdown with unique task identifiers (T001, T002, etc.), acceptance criteria per task, beads issue references, and estimated effort
📚 Learning: 2025-11-25T19:08:54.154Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T19:08:54.154Z
Learning: Applies to specs/*/tasks.md : Feature task files (tasks.md) must include phase-by-phase task breakdown with unique task identifiers (T001, T002, etc.), acceptance criteria per task, beads issue references, and estimated effort

Applied to files:

  • docs/code-review/2026-01-08-taskstats-phase-awareness-review.md
  • web-ui/src/components/Dashboard.tsx
  • web-ui/src/components/tasks/TaskStats.tsx
  • web-ui/__tests__/components/tasks/TaskStats.test.tsx
📚 Learning: 2026-01-04T06:26:12.870Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T06:26:12.870Z
Learning: Applies to web-ui/src/components/Dashboard.tsx : Use React.memo on all Dashboard sub-components and useMemo for derived state to optimize performance with multi-agent support

Applied to files:

  • web-ui/src/components/Dashboard.tsx
  • web-ui/src/components/tasks/TaskStats.tsx
📚 Learning: 2026-01-04T06:26:12.870Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T06:26:12.870Z
Learning: Applies to web-ui/src/contexts/AgentStateContext.ts : Use context-based state management with React Context + useReducer pattern for Dashboard with AgentStateContext, agentReducer, and useAgentState hook

Applied to files:

  • web-ui/src/components/tasks/TaskStats.tsx
📚 Learning: 2025-11-25T19:08:37.203Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-11-25T19:08:37.203Z
Learning: Applies to docs/web-ui/**/__tests__/**/*.test.{ts,tsx} : Create JavaScript test files colocated or in __tests__/ as *.test.ts

Applied to files:

  • web-ui/__tests__/components/tasks/TaskStats.test.tsx
🧬 Code graph analysis (1)
web-ui/src/components/tasks/TaskStats.tsx (2)
web-ui/src/types/api.ts (1)
  • IssuesResponse (106-112)
web-ui/src/hooks/useAgentState.ts (1)
  • useAgentState (156-469)
🪛 markdownlint-cli2 (0.18.1)
docs/code-review/2026-01-08-taskstats-phase-awareness-review.md

43-43: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


49-49: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


215-215: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Backend Unit Tests
  • GitHub Check: Frontend Unit Tests
  • GitHub Check: E2E Smoke Tests (Chromium)
🔇 Additional comments (15)
web-ui/src/components/tasks/TaskStats.tsx (5)

1-19: Well-documented component header.

The JSDoc clearly explains the phase-aware behavior, data sources for each phase, and the bug this fixes. This documentation will help future maintainers understand the dual-data-source pattern.


27-45: Props interface is well-designed with clear documentation.

The optional props maintain backward compatibility while enabling phase-aware behavior. The JSDoc for each prop clearly explains the expected values and behavior.


51-72: Helper function correctly handles edge cases.

The calculateStatsFromIssues function properly handles:

  • Missing issuesData (line 57)
  • Issues without a tasks array (line 63 with || [])
  • Correct status matching for all task states

The multiple .filter() calls (lines 68-70) iterate the array 3 times. For typical planning phase task counts (<100), this is acceptable and more readable than a single-pass loop. The outer useMemo ensures this runs infrequently.


85-112: Correct React hooks usage and memoization.

The implementation correctly:

  1. Calls useAgentState() unconditionally (line 87) - following React hooks rules
  2. Uses the hook's data conditionally based on phase
  3. Memoizes stats with all relevant dependencies (line 112)

The dependency array includes all values that affect the computation, ensuring correct cache invalidation.


177-178: Good use of React.memo for performance.

Wrapping the export with React.memo prevents unnecessary re-renders when parent components update but props remain unchanged. This follows the coding guidelines for Dashboard sub-components.

web-ui/src/components/Dashboard.tsx (1)

702-702: Correct integration of phase-aware TaskStats.

The props are properly passed:

  • phase is normalized using the existing normalizePhase helper
  • issuesData comes from the SWR fetch (may be undefined during loading, which TaskStats handles gracefully)

This change enables TaskStats to display accurate task counts during the planning phase while maintaining the existing real-time behavior during development/review.

.beads/issues.jsonl (1)

99-99: Good technical debt tracking.

The new issue (codeframe-7pya) properly documents:

  • The root cause of phase-awareness bugs (dual REST/WebSocket data systems)
  • At-risk components that may need similar fixes
  • The pattern to apply (phase prop, data source selection)
  • Testing strategy for phase transitions

This ensures the broader implications of this fix are tracked for future work.

docs/code-review/2026-01-08-taskstats-phase-awareness-review.md (1)

1-243: Comprehensive code review documentation.

This review report provides valuable project documentation:

  • Clear executive summary with issue counts
  • Detailed analysis of minor optimization opportunities
  • Positive findings highlighting good practices
  • Action items categorized by priority
  • Testing recommendations with coverage status

The static analysis hints about markdown emphasis vs headings (lines 43, 49, 215) are stylistic preferences that don't affect the document's usefulness. The bold text works well for these section markers.

web-ui/__tests__/components/tasks/TaskStats.test.tsx (7)

349-356: Well-structured test documentation.

The comment block clearly explains what the phase-aware tests verify and the data source selection logic. This helps future developers understand the test intent.


359-470: Comprehensive mock data setup.

The mock data structures:

  • Match the IssuesResponse interface with all required fields
  • Include tasks with various statuses (pending, completed, in_progress, blocked)
  • Provide an emptyAgentState helper for consistent test setup

The inline mock objects are verbose but improve test readability by keeping test data close to assertions.


472-488: Core bug fix test: planning phase uses issuesData.

This test directly validates the bug fix - during planning phase with empty agent state, TaskStats should display counts from issuesData rather than showing zeros. The assertions correctly verify all four statistics.


490-526: Development and review phase tests verify agent state usage.

These tests confirm that during development/review phases, TaskStats ignores issuesData and uses real-time agent state. This ensures the existing WebSocket-based behavior is preserved.


528-572: Edge case tests for graceful degradation.

Good coverage of edge cases:

  • undefined issuesData during planning (line 533) - shows zeros without crashing
  • Issues without tasks array (line 568) - handles missing property gracefully

These tests verify the defensive programming in calculateStatsFromIssues.


592-619: Phase transition test validates data source switching.

This test simulates a real-world scenario where a project transitions from planning to development. Using rerender() to verify the component correctly switches from issuesData (4 tasks) to agent state (8 tasks) is an excellent approach.


621-711: API consistency test ensures UI matches backend counts.

This test validates that TaskStats' calculated total matches issuesData.total_tasks. This is important because the Dashboard tab badge uses total_tasks directly, and the values should be consistent to avoid user confusion.

@frankbria frankbria linked an issue Jan 9, 2026 that may be closed by this pull request
@frankbria
frankbria merged commit 1edac57 into main Jan 9, 2026
12 checks passed
@frankbria
frankbria deleted the fix/taskstats-planning-phase-awareness branch January 9, 2026 06:20
@frankbria

Copy link
Copy Markdown
Owner Author

Issue Linkage

This PR fixes #233 (P0-blocker-beta: Tasks do not display on the Task tab).

Related Issues

When this PR is merged, issue #233 should be closed.

frankbria added a commit that referenced this pull request Jan 9, 2026
The previous phase-aware fix (#234) still failed because it tried to
flatten the issues[].tasks arrays, which the API does not populate.
The fix now uses issuesData.total_tasks directly as the authoritative
count during planning phase.

Root cause: API response includes total_tasks count but not nested
task objects. The tab badge correctly used total_tasks (showing 24)
while TaskStats flattened empty arrays (showing 0).

Changes:
- calculateStatsFromIssues now uses total_tasks field for total count
- Still calculates status counts from nested tasks when available
- Added test for production-like scenario with empty tasks arrays
- Added edge case test for missing total_tasks field
frankbria added a commit that referenced this pull request Jan 9, 2026
…iew (#236)

* fix(ui): use total_tasks field directly in TaskStats planning phase

The previous phase-aware fix (#234) still failed because it tried to
flatten the issues[].tasks arrays, which the API does not populate.
The fix now uses issuesData.total_tasks directly as the authoritative
count during planning phase.

Root cause: API response includes total_tasks count but not nested
task objects. The tab badge correctly used total_tasks (showing 24)
while TaskStats flattened empty arrays (showing 0).

Changes:
- calculateStatsFromIssues now uses total_tasks field for total count
- Still calculates status counts from nested tasks when available
- Added test for production-like scenario with empty tasks arrays
- Added edge case test for missing total_tasks field

* fix(ui): TaskReview now requests tasks with include=tasks param

The API's /issues endpoint only populates issue.tasks[] arrays when
include=tasks query param is passed. Without this, TaskReview displayed
"No tasks available for approval" during planning phase.

Changes:
- api.ts: getIssues now accepts options object with cursor and include
- TaskReview: passes { include: 'tasks' } to get nested task data
- Tests: Updated expected API call signatures

* fix: address PR review feedback

TaskReview:
- Add validation guard for non-numeric projectId before approval API call
- Surface user-facing error if projectId is invalid (NaN or <= 0)

TaskStats:
- Replace emoji icons (📋, ✅, 🚫, ⚙️) with Hugeicons components
- Use CheckListIcon, CheckmarkCircle01Icon, Alert02Icon, Loading03Icon
- Aligns with repo guidelines for consistent iconography

Jest mocks:
- Add missing Hugeicons to @hugeicons/react mock
- Refactor mock creation with helper function
frankbria pushed a commit that referenced this pull request Jan 10, 2026
…stDashboard

Implements the phase-awareness pattern (established in TaskStats PR #234) for
three additional components to fix the "late-joining user" bug during planning
phase.

Components updated:
- AgentList: Shows "Agents Ready for Development" message with task count
  during planning phase instead of misleading "No Agents Assigned"
- QualityGatesPanel: Shows "Quality Gates Ready" message during planning
  phase instead of "No tasks available for quality gate evaluation"
- CostDashboard: Shows "Cost Metrics" informational message during planning
  phase and skips unnecessary API calls (performance optimization)

Implementation details:
- Created shared utilities in phaseAwareData.ts:
  - isPlanningPhase(): Check if phase requires special handling
  - extractTasksFromIssuesData(): Flatten nested tasks from API response
  - calculateProgressFromIssuesData(): Compute progress metrics from REST data
  - getPlanningPhaseMessage(): Get component-specific planning messages
- Dashboard passes phase and issuesData props to all updated components
- All components maintain backward compatibility (work without phase prop)

Testing:
- 25 unit tests for phaseAwareData utilities
- 13 unit tests for AgentList phase-awareness
- 8 unit tests for QualityGatesPanel phase-awareness
- 6 unit tests for CostDashboard phase-awareness
- All 1558 tests pass, build succeeds
frankbria added a commit that referenced this pull request Jan 10, 2026
…stDashboard (#241)

* feat(ui): add phase-awareness to AgentList, QualityGatesPanel, and CostDashboard

Implements the phase-awareness pattern (established in TaskStats PR #234) for
three additional components to fix the "late-joining user" bug during planning
phase.

Components updated:
- AgentList: Shows "Agents Ready for Development" message with task count
  during planning phase instead of misleading "No Agents Assigned"
- QualityGatesPanel: Shows "Quality Gates Ready" message during planning
  phase instead of "No tasks available for quality gate evaluation"
- CostDashboard: Shows "Cost Metrics" informational message during planning
  phase and skips unnecessary API calls (performance optimization)

Implementation details:
- Created shared utilities in phaseAwareData.ts:
  - isPlanningPhase(): Check if phase requires special handling
  - extractTasksFromIssuesData(): Flatten nested tasks from API response
  - calculateProgressFromIssuesData(): Compute progress metrics from REST data
  - getPlanningPhaseMessage(): Get component-specific planning messages
- Dashboard passes phase and issuesData props to all updated components
- All components maintain backward compatibility (work without phase prop)

Testing:
- 25 unit tests for phaseAwareData utilities
- 13 unit tests for AgentList phase-awareness
- 8 unit tests for QualityGatesPanel phase-awareness
- 6 unit tests for CostDashboard phase-awareness
- All 1558 tests pass, build succeeds

* fix(ui): address code review feedback for phase-awareness

- Add aria-hidden to decorative icons for accessibility (AgentList, QualityGatesPanel)
- Add data-testid="bot-icon" to BotIcon in AgentList for test selection
- Update React.memo comment in QualityGatesPanel to reflect all props
- Add phase transition test to CostDashboard (planning → development)
- Add performance note to extractTasksFromIssuesData JSDoc

* Add OpenCode workflow for PR review

* ci: add OpenCode PR review workflow with Z.ai model

Creates opencode-review.yml that mirrors claude-code-review.yml functionality
using the Z.ai model via opencode action:

- Triggers on PR open/synchronize
- Skips documentation and config-only changes
- Only reviews substantial changes (5+ files OR 20+ lines)
- Uses same review prompt structure as Claude review
- Leverages ZHIPU_API_KEY for Z.ai model access

This provides an alternative "different model" perspective on PR reviews.

* fix(ci): resolve duplicate Authorization header in OpenCode workflow

* fix(ci): enable write permissions for PR comments

* fix(ci): refine paths-ignore to review workflow changes

* fix(ci): clear global git auth configs to prevent duplicate headers

---------

Co-authored-by: Test User <test@example.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[P0] Tasks do not display on the Task tab on project page

1 participant