Skip to content

feat: added PR count indicator to issue cards on Contribute and Mentee pages#4446

Open
pranav-871 wants to merge 3 commits intoOWASP:mainfrom
pranav-871:feature/pr-count-issue-cards
Open

feat: added PR count indicator to issue cards on Contribute and Mentee pages#4446
pranav-871 wants to merge 3 commits intoOWASP:mainfrom
pranav-871:feature/pr-count-issue-cards

Conversation

@pranav-871
Copy link
Copy Markdown
Contributor

Proposed change
Add an open pull request count indicator to issue cards on the Contribute page and Mentee issues view. When an issue has open pull requests, a blue badge showing the count is displayed on the card, helping contributors quickly identify issues that are already being worked on without clicking through to GitHub.

Resolves #4411

Changes made:
types/card.ts — added optional pullRequestCount?: number prop to CardProps
components/Card.tsx — renders a blue PR count badge when pullRequestCount > 0
app/contribute/page.tsx — passes issue.pullRequests?.length to the Card component
components/IssuesTable.tsx — added optional showPullRequestCount column with safe default of false
components/MenteeIssues.tsx — added PR count badge to the issue metadata row

Note: After investigating production Algolia records, pullRequests is not currently being indexed in the issues index. The frontend implementation is complete and handles missing data gracefully. A follow-up backend change will be needed to index this field where issues are synced to Algolia. Happy to work on that as well, please let me know if I should open a separate issue for the backend change!

Checklist

  • [ x ] Required: I followed the contributing workflow
  • [ x ] Required: I verified that my code works as intended and resolves the issue as described
  • [ x ] Required: I ran make check-test locally: all warnings addressed, tests passed
  • I used AI for code, documentation, tests, or communication related to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 31, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 74009108-abb6-44cc-9f0c-812a598decd7

📥 Commits

Reviewing files that changed from the base of the PR and between 894d1cf and 427edb0.

📒 Files selected for processing (2)
  • frontend/src/components/Card.tsx
  • frontend/src/components/MenteeIssues.tsx
✅ Files skipped from review due to trivial changes (1)
  • frontend/src/components/MenteeIssues.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/components/Card.tsx

Summary by CodeRabbit

  • New Features

    • Cards now show a PR badge like "X open PR(s)" with correct singular/plural and an icon when a count is present.
    • Issues table gains an optional "Open PRs" column that can be toggled on/off; rows show a PR count badge or an em dash when none.
  • Style

    • Issue metadata layout updated to better wrap badges and maintain consistent spacing.
  • Tests

    • Added unit tests for card PR badge behavior and issues table column counts when the PR column is enabled.

Walkthrough

Cards and related UI now surface open pull request counts: Card accepts and renders pullRequestCount; IssuesTable gains an optional PR column and row field; MenteeIssues and Contribute page pass/render PR counts; tests and a react-icons mock were added/updated.

Changes

Cohort / File(s) Summary
Card component & types
frontend/src/components/Card.tsx, frontend/src/types/card.ts
Added optional pullRequestCount?: number to CardProps and Card. Conditionally renders a PR badge with FaCodePullRequest and pluralized text when count is truthy.
Card tests & icon mock
frontend/__tests__/unit/components/Card.test.tsx
Extended react-icons/fa6 Jest mock to include FaCodePullRequest. Added tests verifying PR badge renders when pullRequestCount > 0 and is absent when 0.
IssuesTable component & types
frontend/src/components/IssuesTable.tsx
Added pullRequestCount?: number to IssueRow and showPullRequestCount?: boolean prop. Updated column-count logic, header, row cell rendering (badge or em dash), and empty-state colSpan.
IssuesTable tests
frontend/__tests__/unit/components/IssuesTable.test.tsx
Added tests asserting header column counts when showPullRequestCount is true (with and without assignee column).
Contribute page & MenteeIssues
frontend/src/app/contribute/page.tsx, frontend/src/components/MenteeIssues.tsx
Contribute page passes pullRequestCount={issue.pullRequests?.length} to Card. MenteeIssues imports FaCodePullRequest, adjusts metadata layout to wrap/gap, and conditionally renders PR badge when PRs exist.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • arkid15r
  • kasya
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately describes the main change: adding a PR count indicator to issue cards on both the Contribute and Mentee pages, which is the primary objective of this changeset.
Description check ✅ Passed The PR description is well-related to the changeset, explaining the purpose, listing all modified files, and noting the graceful handling of missing data and backend follow-up work.
Linked Issues check ✅ Passed The PR fully implements the requirements from issue #4411: displaying PR count on issue cards on the Contribute page and extends to the Mentee view, using the existing pullRequests field and handling missing data gracefully.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the stated objective: adding PR count indicators to cards and tables. No unrelated modifications were introduced.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

2 issues found across 7 files

Confidence score: 3/5

  • There is a concrete UI regression risk in frontend/src/components/IssuesTable.tsx: the PR count cell can shift out of alignment with its header when optional columns are enabled together, which is user-visible and can confuse table interpretation.
  • Test coverage is incomplete in frontend/__tests__/unit/components/IssuesTable.test.tsx; current checks validate column count but not pullRequestCount rendering branches, so badge/value display regressions may slip through.
  • Given the medium severity and high confidence on the alignment issue, this carries some merge risk until the column placement logic and targeted rendering assertions are tightened.
  • Pay close attention to frontend/src/components/IssuesTable.tsx, frontend/__tests__/unit/components/IssuesTable.test.tsx - fix column/header alignment and add branch-level assertions for PR-count display.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="frontend/__tests__/unit/components/IssuesTable.test.tsx">

<violation number="1" location="frontend/__tests__/unit/components/IssuesTable.test.tsx:532">
P2: New PR-count tests only check column count and miss actual `pullRequestCount` rendering branches, leaving regressions in badge/value display untested.</violation>
</file>

<file name="frontend/src/components/IssuesTable.tsx">

<violation number="1" location="frontend/src/components/IssuesTable.tsx:153">
P2: PR count cell is rendered in a different column position than its header, causing header/data misalignment when optional columns are enabled together.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (4)
frontend/src/components/IssuesTable.tsx (1)

210-214: Consider adding "open PRs" text for consistency with Card component.

In Card.tsx and MenteeIssues.tsx, the badge displays "{count} open PRs" with full text. Here it only shows the number. While this may be intentional for table density, it creates an inconsistency in how PR counts are displayed across the application.

If you want consistency, consider updating to match:

                   <span className="inline-flex items-center gap-1 rounded-full bg-blue-100 px-2 py-0.5 text-xs font-medium text-blue-700 dark:bg-blue-900/30 dark:text-blue-300">
                     <FaCodePullRequest className="h-3 w-3" />
-                    {issue.pullRequestCount}
+                    {issue.pullRequestCount} open PR{issue.pullRequestCount === 1 ? '' : 's'}
                   </span>

Alternatively, if the compact display is intentional for table space, this is fine as-is since the column header "Open PRs" provides context.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/IssuesTable.tsx` around lines 210 - 214, The PR count
badge in IssuesTable (rendering block that uses issue.pullRequestCount and
FaCodePullRequest) only shows the number, causing UI inconsistency with Card.tsx
and MenteeIssues.tsx which render "{count} open PRs"; update the badge rendering
in IssuesTable.tsx to include the descriptive text (e.g.,
"{issue.pullRequestCount} open PRs") while preserving the same styling and icon
so it matches Card and MenteeIssues components, or intentionally document/leave
it compact if table density is desired.
frontend/__tests__/unit/components/IssuesTable.test.tsx (1)

528-540: Tests verify column counts correctly, but consider adding cell content tests.

The column count tests are valid. Consider adding tests to verify:

  1. PR count badge renders when pullRequestCount > 0
  2. Em-dash renders when pullRequestCount is 0 or undefined
  3. Mobile view behavior with PR counts
🧪 Suggested additional test cases
it('renders PR count badge when pullRequestCount is provided', () => {
  const issueWithPRs: IssueRow = {
    objectID: 'pr-test',
    number: 200,
    title: 'Issue with PRs',
    state: 'open',
    labels: [],
    pullRequestCount: 3,
  }
  render(<IssuesTable issues={[issueWithPRs]} showPullRequestCount={true} />)
  expect(screen.getByText('3')).toBeInTheDocument()
})

it('renders em-dash when pullRequestCount is 0', () => {
  const issueNoPRs: IssueRow = {
    objectID: 'no-pr-test',
    number: 201,
    title: 'Issue without PRs',
    state: 'open',
    labels: [],
    pullRequestCount: 0,
  }
  render(<IssuesTable issues={[issueNoPRs]} showPullRequestCount={true} />)
  expect(screen.getByText('—')).toBeInTheDocument()
})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/__tests__/unit/components/IssuesTable.test.tsx` around lines 528 -
540, Add tests to cover PR count cell rendering in IssuesTable: create IssueRow
test fixtures (e.g., issueWithPRs and issueNoPRs) and render <IssuesTable
issues={[...]} showPullRequestCount={true} /> then assert that when an item has
pullRequestCount > 0 the numeric badge/text is present and when pullRequestCount
is 0 or undefined the em-dash "—" is rendered; also add an optional test
rendering the component in a narrow/mobile layout (e.g., by setting container
width or using a mobile media query mock) to assert PR count
visibility/formatting on small screens.
frontend/src/components/Card.tsx (1)

141-149: Clean implementation of PR count badge.

The conditional rendering correctly checks for both defined and positive values. The styling is consistent with the badge in MenteeIssues.tsx.

Same optional refactor applies for the pluralization condition on line 146 if you want to address the SonarCloud warning:

♻️ Optional refactor for positive condition
               <span className="inline-flex items-center gap-1 rounded-full bg-blue-100 px-2 py-0.5 text-xs font-medium text-blue-700 dark:bg-blue-900/30 dark:text-blue-300">
                 <FaCodePullRequest className="h-3 w-3" />
-                {pullRequestCount} open PR{pullRequestCount !== 1 ? 's' : ''}
+                {pullRequestCount} open PR{pullRequestCount === 1 ? '' : 's'}
               </span>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/Card.tsx` around lines 141 - 149, The pluralization
check in the PR badge uses "pullRequestCount !== 1 ? 's' : ''" which triggers a
SonarCloud style warning; update the expression to use a clearer numeric
comparison (pullRequestCount > 1) for pluralization and keep the existing
conditional rendering (pullRequestCount !== undefined && pullRequestCount > 0)
intact—change the ternary in the Card component where FaCodePullRequest and
pullRequestCount are rendered so it reads the plural suffix based on
pullRequestCount > 1.
frontend/src/components/MenteeIssues.tsx (1)

89-95: Consider using a positive condition for pluralization (optional).

SonarCloud flags the negated condition on line 93. While the current pattern is idiomatic for pluralization, you could use a ternary with positive logic for consistency with linting preferences:

♻️ Optional refactor for positive condition
                     <FaCodePullRequest className="h-3 w-3" />
-                    {issue.pullRequests.length} open PR
-                    {issue.pullRequests.length !== 1 ? 's' : ''}
+                    {issue.pullRequests.length} open PR{issue.pullRequests.length === 1 ? '' : 's'}
                   </span>

Alternatively, this is a valid pattern that's clear and readable—you may choose to suppress this warning if preferred.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/components/MenteeIssues.tsx` around lines 89 - 95, The
pluralization uses a negated condition; update the ternary in the PR-count span
(inside MenteeIssues.tsx where the FaCodePullRequest badge is rendered) to use a
positive check instead: replace the "!== 1" branch with a positive equality
check (issue.pullRequests.length === 1 ? '' : 's') so the logic is expressed
positively while keeping the same rendered text and spacing.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/src/components/IssuesTable.tsx`:
- Around line 207-219: The PR Count cell (controlled by showPullRequestCount and
rendering issue.pullRequestCount) is placed before Assignee and Deadline causing
header/body mismatch; remove the current PR Count block and re-insert it after
the Deadline cell in the table body so the order matches the header (Title →
Status → Labels → [Assignee] → [Deadline] → [Open PRs]); ensure you keep the
same conditional (showPullRequestCount) and rendering (issue.pullRequestCount
!== undefined && issue.pullRequestCount > 0 ? ... : "—") when moving it.

---

Nitpick comments:
In `@frontend/__tests__/unit/components/IssuesTable.test.tsx`:
- Around line 528-540: Add tests to cover PR count cell rendering in
IssuesTable: create IssueRow test fixtures (e.g., issueWithPRs and issueNoPRs)
and render <IssuesTable issues={[...]} showPullRequestCount={true} /> then
assert that when an item has pullRequestCount > 0 the numeric badge/text is
present and when pullRequestCount is 0 or undefined the em-dash "—" is rendered;
also add an optional test rendering the component in a narrow/mobile layout
(e.g., by setting container width or using a mobile media query mock) to assert
PR count visibility/formatting on small screens.

In `@frontend/src/components/Card.tsx`:
- Around line 141-149: The pluralization check in the PR badge uses
"pullRequestCount !== 1 ? 's' : ''" which triggers a SonarCloud style warning;
update the expression to use a clearer numeric comparison (pullRequestCount > 1)
for pluralization and keep the existing conditional rendering (pullRequestCount
!== undefined && pullRequestCount > 0) intact—change the ternary in the Card
component where FaCodePullRequest and pullRequestCount are rendered so it reads
the plural suffix based on pullRequestCount > 1.

In `@frontend/src/components/IssuesTable.tsx`:
- Around line 210-214: The PR count badge in IssuesTable (rendering block that
uses issue.pullRequestCount and FaCodePullRequest) only shows the number,
causing UI inconsistency with Card.tsx and MenteeIssues.tsx which render
"{count} open PRs"; update the badge rendering in IssuesTable.tsx to include the
descriptive text (e.g., "{issue.pullRequestCount} open PRs") while preserving
the same styling and icon so it matches Card and MenteeIssues components, or
intentionally document/leave it compact if table density is desired.

In `@frontend/src/components/MenteeIssues.tsx`:
- Around line 89-95: The pluralization uses a negated condition; update the
ternary in the PR-count span (inside MenteeIssues.tsx where the
FaCodePullRequest badge is rendered) to use a positive check instead: replace
the "!== 1" branch with a positive equality check (issue.pullRequests.length ===
1 ? '' : 's') so the logic is expressed positively while keeping the same
rendered text and spacing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: cb175730-ee56-4d8c-852c-0bb5d376dc9a

📥 Commits

Reviewing files that changed from the base of the PR and between a058029 and d62d4ca.

📒 Files selected for processing (7)
  • frontend/__tests__/unit/components/Card.test.tsx
  • frontend/__tests__/unit/components/IssuesTable.test.tsx
  • frontend/src/app/contribute/page.tsx
  • frontend/src/components/Card.tsx
  • frontend/src/components/IssuesTable.tsx
  • frontend/src/components/MenteeIssues.tsx
  • frontend/src/types/card.ts

coderabbitai[bot]
coderabbitai bot previously approved these changes Mar 31, 2026
Copy link
Copy Markdown
Contributor Author

@pranav-871 pranav-871 left a comment

Choose a reason for hiding this comment

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

done

@kasya
Copy link
Copy Markdown
Collaborator

kasya commented Apr 5, 2026

@pranav-871 hi! Please address Sonar issues that were introduced in this PR:
Screenshot 2026-04-05 at 11 45 13 AM

coderabbitai[bot]
coderabbitai bot previously approved these changes Apr 5, 2026
cubic-dev-ai[bot]
cubic-dev-ai bot previously approved these changes Apr 5, 2026
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

0 issues found across 2 files (changes from recent commits).

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 5, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

0 issues found across 2 files (changes from recent commits).

@pranav-871
Copy link
Copy Markdown
Contributor Author

Hi @kasya ! I've addressed both SonarQube issues, replaced negated conditions with positive equivalents in Card.tsx and MenteeIssues.tsx

@taditharun
Copy link
Copy Markdown
Contributor

Hii @pranav-871, nice work! Does this badge also show on mobile view? thanks!

@pranav-871
Copy link
Copy Markdown
Contributor Author

Hii @pranav-871, nice work! Does this badge also show on mobile view? thanks!

Hi! Yes, the badge is rendered inside a flex flex-wrap container so it adapts naturally to mobile screens as well. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add PR count on issue cards in contribute page

3 participants