|
| 1 | +# Plan: Team Page — Show Issue/PR Details and Activity Feed |
| 2 | + |
| 3 | +## Metadata |
| 4 | +- **ID**: plan-2026-04-01-team-page-detail |
| 5 | +- **Status**: draft |
| 6 | +- **Specification**: codev/specs/650-team-page-show-issue-pr-detail.md |
| 7 | +- **Created**: 2026-04-01 |
| 8 | + |
| 9 | +## Executive Summary |
| 10 | +Expand the team page to show individual issue/PR titles with GitHub links (instead of just counts) and add a combined activity feed. Requires a minimal backend fix to add `url` to recent activity GraphQL fragments, then frontend changes to `TeamView.tsx` and `index.css`. |
| 11 | + |
| 12 | +## Success Metrics |
| 13 | +- [ ] Member cards show issue/PR titles with clickable GitHub links |
| 14 | +- [ ] Combined activity feed below Messages section |
| 15 | +- [ ] Activity feed sorted reverse chronologically with correct attribution |
| 16 | +- [ ] Empty states handled (`github_data: null` hides sections; empty arrays show text) |
| 17 | +- [ ] Long titles truncated with ellipsis |
| 18 | +- [ ] Build passes, no regressions |
| 19 | + |
| 20 | +## Phases (Machine Readable) |
| 21 | + |
| 22 | +```json |
| 23 | +{ |
| 24 | + "phases": [ |
| 25 | + {"id": "backend-url-fix", "title": "Add URL to recent activity data"}, |
| 26 | + {"id": "expanded-member-cards", "title": "Expand member cards with issue/PR lists"}, |
| 27 | + {"id": "activity-feed", "title": "Add combined activity feed"} |
| 28 | + ] |
| 29 | +} |
| 30 | +``` |
| 31 | + |
| 32 | +## Phase Breakdown |
| 33 | + |
| 34 | +### Phase 1: Add URL to recent activity data |
| 35 | +**Dependencies**: None |
| 36 | + |
| 37 | +#### Objectives |
| 38 | +- Add `url` field to merged PRs and closed issues in the GraphQL query and types |
| 39 | + |
| 40 | +#### Deliverables |
| 41 | +- [ ] Updated GraphQL query fragments in `team-github.ts` |
| 42 | +- [ ] Updated TypeScript types in `team-github.ts` and `api.ts` |
| 43 | +- [ ] Updated response parsing to include `url` |
| 44 | + |
| 45 | +#### Implementation Details |
| 46 | + |
| 47 | +**File: `packages/codev/src/lib/team-github.ts`** |
| 48 | +- `TeamMemberGitHubData.recentActivity.mergedPRs`: add `url: string` to type (line 26) |
| 49 | +- `TeamMemberGitHubData.recentActivity.closedIssues`: add `url: string` to type (line 27) |
| 50 | +- GraphQL query `_merged` fragment (line 94): add `url` → `nodes { ... on PullRequest { number title url mergedAt } }` |
| 51 | +- GraphQL query `_closed` fragment (line 97): add `url` → `nodes { ... on Issue { number title url closedAt } }` |
| 52 | +- `parseTeamGraphQLResponse` (lines 123-124): update type casts and map to include `url` |
| 53 | + |
| 54 | +**File: `packages/codev/dashboard/src/lib/api.ts`** |
| 55 | +- `TeamMemberGitHubData.recentActivity.mergedPRs`: add `url: string` (line 60) |
| 56 | +- `TeamMemberGitHubData.recentActivity.closedIssues`: add `url: string` (line 61) |
| 57 | + |
| 58 | +#### Acceptance Criteria |
| 59 | +- [ ] `url` field present on all recent activity items |
| 60 | +- [ ] Update existing unit test mocks in `team-github.test.ts` to include `url` field |
| 61 | +- [ ] Existing unit tests still pass |
| 62 | +- [ ] Build succeeds |
| 63 | + |
| 64 | +--- |
| 65 | + |
| 66 | +### Phase 2: Expand member cards with issue/PR lists |
| 67 | +**Dependencies**: Phase 1 |
| 68 | + |
| 69 | +#### Objectives |
| 70 | +- Replace count-only display with individual issue/PR title lists in `MemberCard` |
| 71 | + |
| 72 | +#### Deliverables |
| 73 | +- [ ] Updated `MemberCard` component showing issue/PR titles |
| 74 | +- [ ] CSS styles for issue/PR lists |
| 75 | +- [ ] Empty state handling |
| 76 | + |
| 77 | +#### Implementation Details |
| 78 | + |
| 79 | +**File: `packages/codev/dashboard/src/components/TeamView.tsx`** |
| 80 | +- Replace the `team-member-stats` div (lines 29-32) with two sections: |
| 81 | + - "Working on" section: render `gh.assignedIssues` as a list of `<a>` tags with `#{number} {title}` |
| 82 | + - "Open PRs" section: render `gh.openPRs` as a list of `<a>` tags with `#{number} {title}` |
| 83 | +- When `github_data` is `null`: hide both sections entirely |
| 84 | +- When arrays are empty: show "No assigned issues" / "No open PRs" text |
| 85 | +- Keep existing recent activity summary (merged/closed counts with "last 7d") |
| 86 | + |
| 87 | +**File: `packages/codev/dashboard/src/index.css`** |
| 88 | +- Add styles for `.team-member-issues` and `.team-member-prs` list containers |
| 89 | +- Style `.team-item-link`: `display: block`, `text-overflow: ellipsis`, `overflow: hidden`, `white-space: nowrap` (block-level with constrained width for ellipsis to work) |
| 90 | +- Style section labels (small, muted headers for "Working on" / "Open PRs") |
| 91 | + |
| 92 | +#### Acceptance Criteria |
| 93 | +- [ ] Each issue/PR title displayed as clickable link |
| 94 | +- [ ] Links open in new tab with `noopener noreferrer` |
| 95 | +- [ ] Long titles truncated with ellipsis |
| 96 | +- [ ] `github_data: null` hides sections |
| 97 | +- [ ] Empty arrays show placeholder text |
| 98 | + |
| 99 | +--- |
| 100 | + |
| 101 | +### Phase 3: Add combined activity feed |
| 102 | +**Dependencies**: Phase 1, Phase 2 |
| 103 | + |
| 104 | +#### Objectives |
| 105 | +- Add a unified activity timeline below the Messages section |
| 106 | + |
| 107 | +#### Deliverables |
| 108 | +- [ ] New `ActivityFeed` component |
| 109 | +- [ ] CSS styles for activity feed |
| 110 | +- [ ] Relative date formatting helper |
| 111 | + |
| 112 | +#### Implementation Details |
| 113 | + |
| 114 | +**File: `packages/codev/dashboard/src/components/TeamView.tsx`** |
| 115 | +- Add `ActivityFeed` component that: |
| 116 | + 1. Aggregates `recentActivity.mergedPRs` and `recentActivity.closedIssues` across all members |
| 117 | + 2. Tags each item with the member's `name` and `github` handle |
| 118 | + 3. Sorts by timestamp (mergedAt/closedAt) in reverse chronological order |
| 119 | + 4. Renders each entry as: `{relativeDate} @{github} {merged|closed} #{number} {title}` |
| 120 | + 5. Each entry rendered as a single `<a>` anchor wrapping the entire row (entire row clickable), with `target="_blank"` and `rel="noopener noreferrer"`, linking to GitHub via `url` field |
| 121 | +- Add inline `relativeDate(isoString: string)` helper: returns "just now" (<1h), "Xh ago" (1-23h), "Xd ago" (1d+) |
| 122 | +- Add the feed as a third section in `TeamView` after Messages |
| 123 | +- Show "No recent activity" when feed is empty |
| 124 | + |
| 125 | +**File: `packages/codev/dashboard/src/index.css`** |
| 126 | +- Style `.team-activity-feed` container |
| 127 | +- Style `.team-activity-entry`: row layout, muted date, action text |
| 128 | +- Style `.team-activity-author`: `@handle` display |
| 129 | + |
| 130 | +#### Acceptance Criteria |
| 131 | +- [ ] Activity feed shows entries from all members |
| 132 | +- [ ] Entries sorted reverse chronologically |
| 133 | +- [ ] Relative dates display correctly |
| 134 | +- [ ] Links open in new tab |
| 135 | +- [ ] Empty state shows "No recent activity" |
| 136 | + |
| 137 | +## Dependency Map |
| 138 | +``` |
| 139 | +Phase 1 (backend-url-fix) ──→ Phase 2 (expanded-member-cards) ──→ Phase 3 (activity-feed) |
| 140 | +``` |
| 141 | + |
| 142 | +## Risk Analysis |
| 143 | +| Risk | Probability | Impact | Mitigation | |
| 144 | +|------|------------|--------|------------| |
| 145 | +| GraphQL url field not available | Very Low | Medium | Verified: GitHub API exposes `url` on Issue and PullRequest | |
| 146 | +| CSS layout breakage on narrow widths | Low | Low | Existing `minmax(200px, 1fr)` grid handles this; add `text-overflow: ellipsis` | |
| 147 | + |
| 148 | +## Validation Checkpoints |
| 149 | +1. **After Phase 1**: `npm run build` passes, types are consistent |
| 150 | +2. **After Phase 2**: Member cards render titles in dashboard |
| 151 | +3. **After Phase 3**: Full feature complete, activity feed renders correctly |
| 152 | + |
| 153 | +## Expert Review |
| 154 | +**Date**: 2026-04-01 |
| 155 | +**Models Consulted**: Gemini, Codex, Claude |
| 156 | +**Key changes from consultation**: |
| 157 | +- Added explicit unit test update task for Phase 1 (Gemini, Codex) |
| 158 | +- Specified "entire row clickable" as single `<a>` anchor for activity feed (Codex) |
| 159 | +- Added "just now" fallback for sub-1h relative dates (Codex) |
| 160 | +- Clarified CSS ellipsis requires block-level display (Gemini) |
| 161 | + |
| 162 | +## Approval |
| 163 | +- [ ] Technical Lead Review |
| 164 | +- [x] Expert AI Consultation Complete |
0 commit comments