Skip to content

Unify issues view between module issues page and Mentee page#3050

Merged
kasya merged 6 commits intomainfrom
unify-issues-list
Dec 29, 2025
Merged

Unify issues view between module issues page and Mentee page#3050
kasya merged 6 commits intomainfrom
unify-issues-list

Conversation

@kasya
Copy link
Collaborator

@kasya kasya commented Dec 27, 2025

Updated the Mentorship portal Mentee page to display assigned issues using the same table view as the module page. Introduced a reusable IssuesTable.tsx component shared across multiple views.

Checklist

  • Required: I read and followed the contributing guidelines
  • Required: I ran make check-test locally and all tests passed
  • I used AI for code, documentation, or tests in this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 27, 2025

Summary by CodeRabbit

Release Notes

  • New Features
    • Added status filtering (Open, Closed, All) for mentee issues
    • Implemented pagination controls for browsing issues
    • Enhanced issue display with improved status badges, labels, and assignee information
    • Improved responsive design across mobile and desktop views

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

Walkthrough

Adds a reusable IssuesTable component and IssueRow type; replaces inline issue rendering in two pages with IssuesTable, adds client-side pagination and status filtering on the mentee page, extends GraphQL queries to include isMerged, and updates/expands related unit tests.

Changes

Cohort / File(s) Change Summary
New Component
frontend/src/components/IssuesTable.tsx
New client-side React component exporting IssueRow and rendering responsive issues table with title (clickable, tooltip), status badge (open/closed/merged), labels with truncation and "+N more", optional assignee column, and empty state.
Pages — Integration
frontend/src/app/my/mentorship/programs/.../issues/page.tsx, frontend/src/app/my/mentorship/programs/.../mentees/.../page.tsx
Replaced inline desktop/table and mobile/card render with IssuesTable. Mentee page: added client-side pagination, status filter, mapping to IssueRow, ITEMS_PER_PAGE, and memoized navigation handlers. Issues page: memoized handleIssueClick and removed local label trimming.
Tests — New & Updated
frontend/__tests__/unit/components/IssuesTable.test.tsx, frontend/__tests__/unit/pages/IssuesPage.test.tsx, frontend/__tests__/unit/pages/MenteeProfilePage.test.tsx
Added comprehensive IssuesTable tests (rendering, badges, labels, assignees, tooltip, mobile/desktop, accessibility). Adjusted IssuesPage assertions counts/patterns. Expanded MenteeProfilePage mocks (useRouter, Tooltip, Select/SelectItem), updated interaction approach and empty-state expectations.
GraphQL Query
frontend/src/server/queries/menteeQueries.ts
Added isMerged field to getMenteeModuleIssues selection set to include merge state in issue data returned.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • arkid15r

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the primary change: unifying the issues view between the module issues page and the Mentee page through a shared component.
Description check ✅ Passed The description clearly explains the changes: updating the Mentee page to use the same table view as the module page and introducing a reusable IssuesTable component.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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 unify-issues-list

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
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: 0

🧹 Nitpick comments (7)
frontend/__tests__/unit/components/IssuesTable.test.tsx (2)

247-254: Consider removing or differentiating this duplicate test.

This test case is functionally identical to the "calls onIssueClick when provided" test (lines 238-245). Both tests render the same component, click the same element, and verify the same callback invocation. To add value, consider either:

  1. Removing this test as redundant, or
  2. Differentiating by simulating a narrower viewport or verifying mobile-specific behavior

285-303: Tooltip tests don't verify actual tooltip behavior.

These tests verify that buttons render for long and short titles but don't actually assert tooltip behavior (e.g., tooltip visibility, isDisabled prop effect). The test names suggest tooltip verification but the assertions only confirm button presence.

Consider adding assertions that verify the tooltip is disabled for short titles or visible for long titles, perhaps by querying for tooltip-related attributes or using a more detailed mock.

frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/mentees/[menteeKey]/page.tsx (2)

27-39: Consider extracting the inline type to a shared definition.

This inline type closely mirrors parts of IssueRow from IssuesTable.tsx. While not blocking, extracting this to a shared type or reusing existing types would improve maintainability and reduce duplication.


68-78: Assignees are fetched but not mapped to IssueRow.

The GraphQL query fetches assignees data (line 37), but the useMemo mapping doesn't include them in the resulting IssueRow[]. While this works because showAssignee={false} on line 218, including the assignees in the mapping would maintain data completeness and avoid issues if the display option changes in the future.

🔎 Proposed fix
 const menteeIssues: IssueRow[] = useMemo(() => {
   return menteeIssuesData.map((issue) => ({
     objectID: issue.id,
     number: issue.number,
     title: issue.title,
     state: issue.state,
     isMerged: issue.isMerged,
     labels: issue.labels || [],
     url: issue.url,
+    assignees: issue.assignees || [],
   }))
 }, [menteeIssuesData])
frontend/src/components/IssuesTable.tsx (2)

175-178: Display preference should favor name over login.

The current logic login || name prefers the GitHub login over the display name. Typically, the human-readable name is preferred for display with login as the fallback when name is empty.

🔎 Proposed fix
 <span className="max-w-[80px] truncate sm:max-w-[100px] md:max-w-[120px] lg:max-w-[150px]">
-  {issue.assignees[0].login || issue.assignees[0].name}
+  {issue.assignees[0].name || issue.assignees[0].login}
   {issue.assignees.length > 1 && ` +${issue.assignees.length - 1}`}
 </span>

146-152: Consider using a unique key for label elements.

Using label as the key could cause issues if duplicate labels exist in the array (though unlikely). Consider using the index or a combination of label and index for guaranteed uniqueness.

🔎 Proposed fix
-{issue.labels.slice(0, maxVisibleLabels).map((label) => (
+{issue.labels.slice(0, maxVisibleLabels).map((label, index) => (
   <span
-    key={label}
+    key={`${label}-${index}`}
     className="inline-flex items-center rounded-md bg-gray-100 px-2 py-0.5 text-xs text-gray-700 lg:rounded-lg lg:border lg:border-gray-400 lg:bg-transparent lg:hover:bg-gray-200 dark:bg-gray-800 dark:text-gray-300 dark:lg:border-gray-300 dark:lg:hover:bg-gray-700"
   >
     {label}
   </span>
 ))}
frontend/__tests__/unit/pages/MenteeProfilePage.test.tsx (1)

104-109: Type assertion may fail for non-element children.

The React.Children.map callback casts each child as React.ReactElement, which could cause runtime issues if non-element children (like strings or nulls) are passed. Consider adding a type guard.

🔎 Proposed fix
 {React.Children.map(children, (child) => {
+  if (!React.isValidElement(child)) {
+    return child
+  }
   const itemKey = String(child.key ?? '')
   return React.cloneElement(child, {
     'data-key': itemKey,
     onClick: () => handleItemClick(itemKey),
   } as Partial<unknown>)
 })}
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5273656 and 48a8714.

⛔ Files ignored due to path filters (1)
  • frontend/src/types/__generated__/menteeQueries.generated.ts is excluded by !**/__generated__/**
📒 Files selected for processing (7)
  • frontend/__tests__/unit/components/IssuesTable.test.tsx
  • frontend/__tests__/unit/pages/IssuesPage.test.tsx
  • frontend/__tests__/unit/pages/MenteeProfilePage.test.tsx
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/issues/page.tsx
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/mentees/[menteeKey]/page.tsx
  • frontend/src/components/IssuesTable.tsx
  • frontend/src/server/queries/menteeQueries.ts
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 2000
File: backend/apps/mentorship/management/commands/sync_module_issues.py:109-145
Timestamp: 2025-08-17T11:55:55.990Z
Learning: In the OWASP/Nest mentorship system, tasks are designed to be assigned to only one assignee per issue, even if GitHub issues can have multiple assignees. The sync_module_issues command correctly uses issue.assignees.first() to create one task per issue for the first assignee only.
📚 Learning: 2025-07-13T07:31:06.511Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/components/ModuleCard.tsx:53-55
Timestamp: 2025-07-13T07:31:06.511Z
Learning: In Next.js 13+ app router, useRouter from 'next/navigation' does not provide asPath or query properties. Use useParams to extract route parameters and usePathname to get the current pathname instead.

Applied to files:

  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/issues/page.tsx
  • frontend/__tests__/unit/pages/MenteeProfilePage.test.tsx
📚 Learning: 2025-08-31T13:47:15.861Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2155
File: frontend/src/server/queries/programsQueries.ts:81-81
Timestamp: 2025-08-31T13:47:15.861Z
Learning: In frontend/src/server/queries/programsQueries.ts, GET_PROGRAM_DETAILS is actively used in frontend/src/app/my/mentorship/programs/[programKey]/edit/page.tsx for program editing functionality and cannot be removed. It serves a different purpose than GET_PROGRAM_ADMIN_DETAILS, providing comprehensive program information needed for editing.

Applied to files:

  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/issues/page.tsx
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/mentees/[menteeKey]/page.tsx
📚 Learning: 2025-11-17T16:47:05.578Z
Learnt from: anurag2787
Repo: OWASP/Nest PR: 2671
File: frontend/__tests__/unit/components/MultiSearch.test.tsx:427-427
Timestamp: 2025-11-17T16:47:05.578Z
Learning: In the frontend test files for the OWASP/Nest repository, `expect(true).toBe(true)` no-op assertions may be intentionally added as workarounds when ESLint rule jest/expect-expect doesn't detect expectations inside helper functions or waitFor callbacks. These can be resolved by configuring the ESLint rule's assertFunctionNames option to recognize custom assertion helpers instead of flagging them as redundant.

Applied to files:

  • frontend/__tests__/unit/components/IssuesTable.test.tsx
  • frontend/__tests__/unit/pages/MenteeProfilePage.test.tsx
  • frontend/__tests__/unit/pages/IssuesPage.test.tsx
📚 Learning: 2025-07-12T17:36:57.255Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/__tests__/unit/pages/createProgram.test.tsx:70-86
Timestamp: 2025-07-12T17:36:57.255Z
Learning: When testing React page components that use mocked form components, validation logic should be tested at the form component level, not the page level. Page-level tests should focus on authentication, role checking, submission handling, and navigation logic.

Applied to files:

  • frontend/__tests__/unit/pages/MenteeProfilePage.test.tsx
📚 Learning: 2025-07-13T11:29:25.245Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/app/mentorship/programs/page.tsx:59-61
Timestamp: 2025-07-13T11:29:25.245Z
Learning: In Next.js 13+ app router, components with the 'use client' directive run entirely on the client side and don't require window object existence checks or SSR hydration considerations. Direct access to window.location and other browser APIs is safe in client components.

Applied to files:

  • frontend/__tests__/unit/pages/MenteeProfilePage.test.tsx
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/mentees/[menteeKey]/page.tsx
📚 Learning: 2025-11-17T17:30:42.139Z
Learnt from: anurag2787
Repo: OWASP/Nest PR: 2671
File: frontend/__tests__/unit/components/MultiSearch.test.tsx:169-171
Timestamp: 2025-11-17T17:30:42.139Z
Learning: In the OWASP/Nest frontend tests (PR #2671 context), wrapper functions like `expectChaptersCountEqualsThree` that simply call another helper with a fixed parameter (e.g., `expectChaptersCountEquals(3)`) are intentionally used to avoid arrow function callbacks in `waitFor` calls. This pattern prevents adding nesting depth that would trigger rule typescript:S2004. Example: `await waitFor(expectChaptersCountEqualsThree)` avoids the extra nesting from `await waitFor(() => expectChaptersCountEquals(3))`.

Applied to files:

  • frontend/__tests__/unit/pages/MenteeProfilePage.test.tsx
  • frontend/__tests__/unit/pages/IssuesPage.test.tsx
🧬 Code graph analysis (3)
frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/issues/page.tsx (1)
frontend/src/components/IssuesTable.tsx (1)
  • IssueRow (8-18)
frontend/__tests__/unit/components/IssuesTable.test.tsx (1)
frontend/src/components/IssuesTable.tsx (1)
  • IssueRow (8-18)
frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/mentees/[menteeKey]/page.tsx (2)
frontend/src/components/IssuesTable.tsx (1)
  • IssueRow (8-18)
backend/tests/apps/github/models/issue_test.py (1)
  • issue (26-28)
⏰ 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). (4)
  • GitHub Check: Run frontend unit tests
  • GitHub Check: Run frontend e2e tests
  • GitHub Check: Run backend tests
  • GitHub Check: CodeQL (javascript-typescript)
🔇 Additional comments (16)
frontend/src/server/queries/menteeQueries.ts (1)

25-25: LGTM!

The isMerged field addition aligns with the IssueRow type definition in the new IssuesTable component, enabling proper merged state display in the unified issues view.

frontend/__tests__/unit/pages/IssuesPage.test.tsx (2)

92-92: LGTM!

The assertion update correctly reflects the unified empty state rendering from the IssuesTable component, which now displays the message once rather than in multiple places.


261-262: LGTM!

Using regex pattern /\+1/ with getAllByText appropriately handles the "+1" indicator that may appear in both desktop and mobile views rendered by IssuesTable.

frontend/__tests__/unit/components/IssuesTable.test.tsx (1)

1-27: LGTM!

Well-structured mocks for Next.js navigation and Image components. The mock setup appropriately isolates the component for unit testing.

frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/mentees/[menteeKey]/page.tsx (2)

114-119: LGTM!

Using window.open with noopener,noreferrer for external GitHub URLs is appropriate and secure. This correctly differs from the IssuesPage which navigates to an internal detail page.


185-211: LGTM!

The Select component implementation with proper aria-label, selection handling, and page reset on filter change follows good UX and accessibility patterns.

frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/issues/page.tsx (3)

41-51: LGTM!

Clean data transformation to IssueRow[] with proper useMemo memoization. The mapping includes all relevant fields including assignees for display in the table.


84-91: LGTM!

Proper use of useCallback with correct dependencies. This prevents unnecessary re-renders of the IssuesTable component when the parent re-renders.


134-139: LGTM!

The IssuesTable integration consolidates the previous inline rendering logic into a clean, reusable component with consistent props across both pages.

frontend/src/components/IssuesTable.tsx (3)

8-18: LGTM!

Well-defined and exported IssueRow type that provides a consistent contract for issue data across consuming components.


41-47: LGTM!

Clear precedence logic: onIssueClick callback takes priority, falling back to issueUrl for router navigation. This provides flexibility for different navigation behaviors across pages.


49-66: LGTM!

Robust status badge implementation with proper handling of the merged state override and a sensible fallback to "Closed" for unknown states.

frontend/__tests__/unit/pages/MenteeProfilePage.test.tsx (4)

41-60: LGTM!

Clean Tooltip mock that properly handles the isDisabled prop to return children directly or wrap them with test attributes.


62-139: Well-crafted Select component mock.

The mock properly simulates open/close state, selection changes, and item rendering, enabling robust interaction testing. This is a good pattern for testing components that use complex UI libraries.


228-240: LGTM!

Adding explicit null checks with descriptive error messages improves test reliability and debugging when the DOM structure doesn't match expectations.


251-274: LGTM!

Updated filter tests correctly use the new test IDs and verify filtering behavior through the custom Select mock. The assertions properly check for presence/absence of filtered issues.

coderabbitai[bot]
coderabbitai bot previously approved these changes Dec 27, 2025
Copy link
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: 0

🧹 Nitpick comments (4)
frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/mentees/[menteeKey]/page.tsx (1)

108-113: Consider memoizing the click handler for performance.

The implementation is correct and secure (good use of noopener,noreferrer). However, since this function is passed to IssuesTable, consider wrapping it in useCallback to prevent unnecessary re-renders when the menteeIssues reference changes due to pagination or filtering.

🔎 Proposed optimization
- const handleIssueClick = (issueNumber: number) => {
+ const handleIssueClick = useCallback((issueNumber: number) => {
    const issue = menteeIssues.find((i) => i.number === issueNumber)
    if (issue?.url) {
      window.open(issue.url, '_blank', 'noopener,noreferrer')
    }
- }
+ }, [menteeIssues])
frontend/__tests__/unit/components/IssuesTable.test.tsx (3)

112-120: Consider more specific assertions.

While the test correctly verifies that issue rows are rendered, checking length > 0 is somewhat loose. Consider being more explicit about the expected count for more reliable tests.

🔎 Example of more specific assertion
  it('renders all issue rows', () => {
    render(<IssuesTable {...defaultProps} />)
    const issue1Buttons = screen.getAllByRole('button', { name: /Test Issue 1/i })
    const issue2Buttons = screen.getAllByRole('button', { name: /Test Issue 2/i })
    const issue3Buttons = screen.getAllByRole('button', { name: /Test Issue 3/i })
-   expect(issue1Buttons.length).toBeGreaterThan(0)
-   expect(issue2Buttons.length).toBeGreaterThan(0)
-   expect(issue3Buttons.length).toBeGreaterThan(0)
+   // Each issue appears in both desktop and mobile views
+   expect(issue1Buttons).toHaveLength(2)
+   expect(issue2Buttons).toHaveLength(2)
+   expect(issue3Buttons).toHaveLength(2)
  })

185-190: Consider more robust DOM queries.

The use of closest('tr')?.querySelector('td:nth-child(3)') is fragile and depends on specific DOM structure. Consider using more semantic queries that are less likely to break with structural changes.

🔎 Alternative approach
  it('does not render labels section when labels array is empty', () => {
    render(<IssuesTable issues={[mockIssues[2]]} />)
-   const issueTitles = screen.getAllByText('Test Issue 3')
-   const labelsCell = issueTitles[0].closest('tr')?.querySelector('td:nth-child(3)')
-   expect(labelsCell?.textContent).toBe('')
+   // Verify no label badges are rendered for this issue
+   const table = screen.getByRole('table')
+   const rows = within(table).getAllByRole('row')
+   const issueRow = rows.find(row => row.textContent?.includes('Test Issue 3'))
+   const labelBadges = issueRow ? within(issueRow).queryAllByRole('status') : []
+   expect(labelBadges).toHaveLength(0)
  })

Note: This assumes labels use appropriate ARIA roles. If not, you might need to query by test-id or class.


230-235: Similar DOM query fragility concern.

The same fragile querying pattern appears here with querySelector('td:nth-child(4)'). Consider applying the same more semantic querying approach suggested for the labels tests.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 48a8714 and 62f6a5e.

📒 Files selected for processing (2)
  • frontend/__tests__/unit/components/IssuesTable.test.tsx
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/mentees/[menteeKey]/page.tsx
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 2000
File: backend/apps/mentorship/management/commands/sync_module_issues.py:109-145
Timestamp: 2025-08-17T11:55:55.990Z
Learning: In the OWASP/Nest mentorship system, tasks are designed to be assigned to only one assignee per issue, even if GitHub issues can have multiple assignees. The sync_module_issues command correctly uses issue.assignees.first() to create one task per issue for the first assignee only.
📚 Learning: 2025-11-17T16:47:05.578Z
Learnt from: anurag2787
Repo: OWASP/Nest PR: 2671
File: frontend/__tests__/unit/components/MultiSearch.test.tsx:427-427
Timestamp: 2025-11-17T16:47:05.578Z
Learning: In the frontend test files for the OWASP/Nest repository, `expect(true).toBe(true)` no-op assertions may be intentionally added as workarounds when ESLint rule jest/expect-expect doesn't detect expectations inside helper functions or waitFor callbacks. These can be resolved by configuring the ESLint rule's assertFunctionNames option to recognize custom assertion helpers instead of flagging them as redundant.

Applied to files:

  • frontend/__tests__/unit/components/IssuesTable.test.tsx
📚 Learning: 2025-08-31T13:47:15.861Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2155
File: frontend/src/server/queries/programsQueries.ts:81-81
Timestamp: 2025-08-31T13:47:15.861Z
Learning: In frontend/src/server/queries/programsQueries.ts, GET_PROGRAM_DETAILS is actively used in frontend/src/app/my/mentorship/programs/[programKey]/edit/page.tsx for program editing functionality and cannot be removed. It serves a different purpose than GET_PROGRAM_ADMIN_DETAILS, providing comprehensive program information needed for editing.

Applied to files:

  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/mentees/[menteeKey]/page.tsx
📚 Learning: 2025-07-13T11:29:25.245Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/app/mentorship/programs/page.tsx:59-61
Timestamp: 2025-07-13T11:29:25.245Z
Learning: In Next.js 13+ app router, components with the 'use client' directive run entirely on the client side and don't require window object existence checks or SSR hydration considerations. Direct access to window.location and other browser APIs is safe in client components.

Applied to files:

  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/mentees/[menteeKey]/page.tsx
🧬 Code graph analysis (2)
frontend/__tests__/unit/components/IssuesTable.test.tsx (1)
frontend/src/components/IssuesTable.tsx (1)
  • IssueRow (8-18)
frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/mentees/[menteeKey]/page.tsx (3)
frontend/src/types/__generated__/menteeQueries.generated.ts (1)
  • GetModuleMenteeDetailsQuery (11-11)
frontend/src/components/IssuesTable.tsx (1)
  • IssueRow (8-18)
backend/tests/apps/github/models/issue_test.py (1)
  • issue (26-28)
⏰ 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). (2)
  • GitHub Check: Run frontend unit tests
  • GitHub Check: Run frontend e2e tests
🔇 Additional comments (16)
frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/mentees/[menteeKey]/page.tsx (6)

4-21: LGTM! Well-organized imports and constants.

The new imports for Select/SelectItem, IssuesTable, and Pagination are properly organized, and the ITEMS_PER_PAGE constant at module level is a good practice for configurability.


30-36: State management is well-typed and initialized correctly.

The state declarations properly leverage TypeScript inference from the GraphQL types, ensuring type safety throughout the component.


86-106: LGTM! Clean filtering and pagination logic.

The filtering logic correctly handles case-insensitive state comparison, and the pagination calculation is accurate. The status filter options with counts provide good user feedback.


179-205: Select component configuration looks good.

The Select component is properly configured with single selection mode, appropriate styling, and the onSelectionChange handler correctly resets pagination when the filter changes—good UX decision.


210-223: IssuesTable and Pagination integration is well-implemented.

The props passed to IssuesTable and Pagination are correct. Setting showAssignee={false} makes sense in the mentee context, and the custom empty message provides good user feedback.


61-72: No action required. The GraphQL query getMenteeModuleIssues includes all fields used in the data transformation, including isMerged. The mapping is complete and correct.

frontend/__tests__/unit/components/IssuesTable.test.tsx (10)

6-48: LGTM! Well-structured test mocks.

The mocks for Next.js router, Image, and HeroUI Tooltip are appropriate for isolated component testing. The Tooltip mock correctly handles the isDisabled prop and exposes data-content for verification.


50-98: Comprehensive mock data covering key scenarios.

The mock issues effectively cover different states (open, closed, merged), varying label and assignee counts, and all required IssueRow fields. This provides good test coverage foundation.


131-162: LGTM! Good coverage of status badge variations.

The tests correctly verify Open, Closed, and Merged status badges, and the test for unknown states defaulting to Closed is a valuable edge case.


237-255: Excellent edge case coverage.

The test for falling back to login when name is empty is particularly valuable and demonstrates thorough edge case consideration.


258-267: LGTM! Click handler test is clear and effective.

The test correctly verifies that the onIssueClick callback is invoked with the expected issue number.


269-295: LGTM! Comprehensive empty state coverage.

The tests effectively verify both default and custom empty messages across desktop and mobile views, ensuring good user experience in edge cases.


297-325: LGTM! Tooltip tests validate the 50-character threshold.

The tests properly verify that tooltips appear for long titles and are disabled for short ones, ensuring good UX for title truncation.


327-358: LGTM! Good responsive behavior coverage.

The tests verify that essential information (status, labels, assignees) is appropriately rendered in mobile view, with reasonable limits (3 labels) for smaller screens.


360-374: LGTM! Clean column count validation.

The tests use semantic queries (getAllByRole('columnheader')) and correctly verify the table structure adapts to the showAssignee prop.


376-399: LGTM! Important default props validation.

Testing default prop values is crucial for API stability and preventing regressions. These tests provide good documentation of expected default behavior.

@kasya kasya marked this pull request as ready for review December 27, 2025 01:05
@kasya kasya requested a review from arkid15r as a code owner December 27, 2025 01:05
@sonarqubecloud
Copy link

Copy link
Collaborator

@arkid15r arkid15r left a comment

Choose a reason for hiding this comment

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

LGTM

import { useRouter } from 'next/navigation'
import type React from 'react'

export type IssueRow = {
Copy link
Collaborator

Choose a reason for hiding this comment

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

type vs interface?

@kasya kasya added this pull request to the merge queue Dec 29, 2025
Merged via the queue into main with commit b782d00 Dec 29, 2025
27 checks passed
@kasya kasya deleted the unify-issues-list branch December 29, 2025 01:41
Mr-Rahul-Paul pushed a commit to Mr-Rahul-Paul/Nest that referenced this pull request Jan 2, 2026
)

* Unify issues view between module issues page and Mentee page

* Clean up tests

* Update tests and mentee page
0xgaurav pushed a commit to 0xgaurav/Nest that referenced this pull request Jan 4, 2026
)

* Unify issues view between module issues page and Mentee page

* Clean up tests

* Update tests and mentee page
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.

2 participants