Skip to content

feat: add My Issues only filter to /issues page#140

Open
blinkeye-lcm wants to merge 2 commits into
MkDev11:mainfrom
blinkeye-lcm:feat/my-issues-only-filter
Open

feat: add My Issues only filter to /issues page#140
blinkeye-lcm wants to merge 2 commits into
MkDev11:mainfrom
blinkeye-lcm:feat/my-issues-only-filter

Conversation

@blinkeye-lcm
Copy link
Copy Markdown
Contributor

@blinkeye-lcm blinkeye-lcm commented May 22, 2026

Summary

Adds a "My Issues only" toggle to /issues, matching the existing "My PRs only" affordance on /pulls. The filter narrows the list to issues opened by the signed-in user, with state synced to the URL via ?mine=1 so the view survives reloads and stays shareable.

Behavior mirrors the pulls page:

  • Sits next to "Tracked only" and uses attention-tone styling to stand out
  • Shows the count of personal issues when greater than zero
  • Mutually exclusive with the author dropdown (selecting an explicit author clears the toggle, and enabling the toggle overrides the dropdown)
  • Highlights the author cell on rows opened by the signed-in user
  • Returns an empty result for signed-out visitors via a sentinel author value, preventing accidental data exposure

The existing inline "Tracked only" button was extracted into a small local ToggleButton helper (same pattern as /pulls) so the two toggles share styling. The "Tracked only" color now matches the pulls page (accent instead of attention), keeping both pages visually consistent.

The Issues page itself now wraps the table in <Suspense> because the table reads useSearchParams(). The docs page also picks up a short bullet describing the new filter.

Related Issues

Closes #139

Screenshot

Screenshot 2026-05-22 192418

Type of Change

  • Bug fix
  • New feature
  • Enhancement
  • Refactor
  • Documentation
  • Other (describe):

Testing

  • pnpm build passes (TypeScript compilation verified via tsc --noEmit)
  • Manual browser smoke test on /issues:
    • Toggling activates the filter, the count appears, and the URL gains ?mine=1
    • Reloading the URL restores the filter state
    • Selecting an explicit author from the dropdown clears the toggle
    • A signed-out session shows an empty list rather than another account's data
    • Rows opened by the signed-in user have their author cell highlighted in attention color
  • N/A (docs / config only)

Checklist

  • Self-reviewed the diff
  • Follows existing code patterns and naming
  • No unrelated changes included
  • Documentation updated to describe the new filter

Summary by CodeRabbit

  • New Features
    • Added "My Issues only" filter to show issues created by the signed-in user; filter state syncs with the URL for bookmarking.
  • UI Improvements
    • Replaced inline toggles with consistent toggle buttons, updated author header styling to highlight your issues, and improved empty-state messaging when filters (including "My Issues only") are active.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

📝 Walkthrough

Walkthrough

Adds a "My Issues only" toggle to the Issues table, synced with the ?mine=1 URL param, with client-side suspense rendering, URL-state synchronization using the current miner login, a reusable ToggleButton, author-based query filtering, and row-level highlighting for the miner's issues.

Changes

My Issues only filter

Layer / File(s) Summary
Page suspense boundary
src/app/issues/page.tsx
IssuesPage imports Suspense and wraps IssuesTable in a Suspense boundary with null fallback, enabling client-side rendering.
Mine-only state and URL synchronization
src/components/IssuesTable.tsx
Reads the mine URL parameter, initializes mineOnly state, fetches miner identity via useMinerLogin(), and adds a memoized setMineOnlyWithUrl callback to sync state with the URL.
ToggleButton and imports
src/components/IssuesTable.tsx
Adds useCallback import and a local ToggleButton component that accepts active, onClick, optional icon, and tone props for filter UI.
Author parameter and query filtering
src/components/IssuesTable.tsx
Derives authorParam from mineOnly and miner login, conditionally includes it in issuesParams, computes myCount from author stats, and updates pagination reset dependencies.
Filter controls and author column UI
src/components/IssuesTable.tsx
Replaces prior inline controls with ToggleButtons, adds "My Issues only" toggle wired to URL sync and displays myCount; updates AuthorFilter/header so selecting an author disables mineOnly.
Row-level mine prop threading and styling
src/components/IssuesTable.tsx
Passes mine boolean prop to each IssueTableRow, updates prop typing, and applies attention/emphasis color to author text when mine is true.
Documentation of the My Issues filter
src/app/docs/page.tsx
Adds a bullet describing the "My Issues only" filter and its ?mine=1 URL synchronization behavior.

Sequence Diagram

sequenceDiagram
  participant User
  participant IssuesPage
  participant IssuesTable
  participant useMinerLogin
  participant IssueTableRow

  User->>IssuesPage: Navigate with ?mine=1
  IssuesPage->>IssuesTable: Render with Suspense
  IssuesTable->>IssuesTable: Parse mine param from URL
  IssuesTable->>useMinerLogin: Fetch current miner identity
  useMinerLogin-->>IssuesTable: Return miner login
  IssuesTable->>IssuesTable: Derive authorParam from mineOnly + miner
  IssuesTable->>IssuesTable: Build issuesParams with author filter
  IssuesTable->>IssueTableRow: Render each row with mine=true/false
  IssueTableRow->>IssueTableRow: Apply attention color if mine=true
  IssueTableRow-->>User: Display highlighted author cell
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Possibly related PRs

  • MkDev11/gittensor-hub#132: Implements the same mine=1 URL parameter synchronization pattern (setMineOnlyWithUrl) and overlaps in mine-only URL sync logic.

Poem

🐰 I nibble the code where filters grow,
Toggle hops on, ?mine=1 in tow.
Rows that are mine wear a brighter hue,
URL and state dance in perfect view.
Hooray — the table knows which issues are you!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: add My Issues only filter to /issues page' clearly and specifically summarizes the main change—adding a new filter feature to the issues page.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

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

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

Copy link
Copy Markdown

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/app/issues/page.tsx (1)

1-3: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Remove ineffective route config from client component.

The export const dynamic = 'force-dynamic' has no effect in a client component. Route segment config options like dynamic only apply to Server Components and Route Handlers in Next.js 15.

Since this page is marked with 'use client', the dynamic export is ignored and serves no purpose.

🧹 Proposed fix
 'use client';
 
-export const dynamic = 'force-dynamic';
-
 import React, { Suspense } from 'react';
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/issues/page.tsx` around lines 1 - 3, The file is a client component
(it starts with 'use client') so the route config export export const dynamic =
'force-dynamic' is ineffective; remove that export from the module (delete the
export const dynamic line) and keep only the client directive and component code
so no server-only route config remains in the client component.
🧹 Nitpick comments (2)
src/app/issues/page.tsx (1)

24-26: 💤 Low value

Consider adding a loading skeleton to the Suspense fallback.

The fallback={null} provides no visual feedback while the table loads. While this may be intentional for a fast render, consider using a skeleton loader to improve perceived performance, especially on slower connections.

💡 Example with skeleton fallback
-        <Suspense fallback={null}>
+        <Suspense fallback={<Box sx={{ p: 4 }}><TableRowsSkeleton rows={8} cols={[...]} /></Box>}>
           <IssuesTable />
         </Suspense>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/issues/page.tsx` around lines 24 - 26, The Suspense wrapper around
IssuesTable currently uses fallback={null}, giving no visual feedback while data
loads; replace the null fallback with a lightweight skeleton component (e.g.,
IssuesTableSkeleton or a generic TableSkeleton) and render that in the Suspense
fallback so users see a loading placeholder; update where Suspense is used
around IssuesTable to import and pass the skeleton component (or create
IssuesTableSkeleton if missing) and ensure its styling matches the table layout
for smooth visual continuity.
src/components/IssuesTable.tsx (1)

613-656: 💤 Low value

Consider removing hardcoded fallback color.

Line 627 includes a hardcoded rgba(242, 201, 76, 0.14) fallback for --attention-subtle, but no fallback for --accent-subtle. This inconsistency might cause unexpected behavior if CSS variables are missing, and the hardcoded value may not match all theme variants.

Modern Primer themes should define these variables, so the fallback is likely unnecessary. Consider removing it for consistency.

♻️ Proposed refactor
-  const subtle = tone === 'attention' ? 'var(--attention-subtle, rgba(242, 201, 76, 0.14))' : 'var(--accent-subtle)';
+  const subtle = tone === 'attention' ? 'var(--attention-subtle)' : 'var(--accent-subtle)';
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/IssuesTable.tsx` around lines 613 - 656, In ToggleButton,
remove the hardcoded RGBA fallback in the subtle color expression so both tones
use only their CSS variables consistently; replace the current use of
"var(--attention-subtle, rgba(242, 201, 76, 0.14))" with
"var(--attention-subtle)" (so subtle is set via var(--attention-subtle) for
'attention' and var(--accent-subtle) for 'accent'), keeping the rest of the
logic and names (emphasis, subtle, tone, active) unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/IssuesTable.tsx`:
- Line 262: The current expression in IssuesTable that computes myCount calls
me.toLowerCase() which throws if me is null/undefined; change the lookup to
guard/normalize me first (e.g., compute a safe string like normalizedMe = (me ??
'').toLowerCase() or short-circuit when me is falsy) and then use normalizedMe
in the authorOptions.find predicate (referencing myCount, authorOptions, and me)
so unauthenticated visitors won't crash the component.

---

Outside diff comments:
In `@src/app/issues/page.tsx`:
- Around line 1-3: The file is a client component (it starts with 'use client')
so the route config export export const dynamic = 'force-dynamic' is
ineffective; remove that export from the module (delete the export const dynamic
line) and keep only the client directive and component code so no server-only
route config remains in the client component.

---

Nitpick comments:
In `@src/app/issues/page.tsx`:
- Around line 24-26: The Suspense wrapper around IssuesTable currently uses
fallback={null}, giving no visual feedback while data loads; replace the null
fallback with a lightweight skeleton component (e.g., IssuesTableSkeleton or a
generic TableSkeleton) and render that in the Suspense fallback so users see a
loading placeholder; update where Suspense is used around IssuesTable to import
and pass the skeleton component (or create IssuesTableSkeleton if missing) and
ensure its styling matches the table layout for smooth visual continuity.

In `@src/components/IssuesTable.tsx`:
- Around line 613-656: In ToggleButton, remove the hardcoded RGBA fallback in
the subtle color expression so both tones use only their CSS variables
consistently; replace the current use of "var(--attention-subtle, rgba(242, 201,
76, 0.14))" with "var(--attention-subtle)" (so subtle is set via
var(--attention-subtle) for 'attention' and var(--accent-subtle) for 'accent'),
keeping the rest of the logic and names (emphasis, subtle, tone, active)
unchanged.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6f328d3f-5ea4-43eb-b103-84399185dc07

📥 Commits

Reviewing files that changed from the base of the PR and between 85ba452 and 179aadb.

📒 Files selected for processing (3)
  • src/app/docs/page.tsx
  • src/app/issues/page.tsx
  • src/components/IssuesTable.tsx

const totalPages = data?.total_pages ?? page;
const safePage = Math.min(page, totalPages);
const authorOptions = data?.authors ?? [];
const myCount = authorOptions.find((a) => a.login.toLowerCase() === me.toLowerCase())?.count ?? 0;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Guard against null/undefined miner login.

Calling me.toLowerCase() will throw a TypeError if me is null or undefined (when user is signed out). This will crash the component for unauthenticated visitors.

🛡️ Proposed fix
-  const myCount = authorOptions.find((a) => a.login.toLowerCase() === me.toLowerCase())?.count ?? 0;
+  const myCount = me ? authorOptions.find((a) => a.login.toLowerCase() === me.toLowerCase())?.count ?? 0 : 0;

Or alternatively:

-  const myCount = authorOptions.find((a) => a.login.toLowerCase() === me.toLowerCase())?.count ?? 0;
+  const myCount = authorOptions.find((a) => me && a.login.toLowerCase() === me.toLowerCase())?.count ?? 0;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const myCount = authorOptions.find((a) => a.login.toLowerCase() === me.toLowerCase())?.count ?? 0;
const myCount = me ? authorOptions.find((a) => a.login.toLowerCase() === me.toLowerCase())?.count ?? 0 : 0;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/IssuesTable.tsx` at line 262, The current expression in
IssuesTable that computes myCount calls me.toLowerCase() which throws if me is
null/undefined; change the lookup to guard/normalize me first (e.g., compute a
safe string like normalizedMe = (me ?? '').toLowerCase() or short-circuit when
me is falsy) and then use normalizedMe in the authorOptions.find predicate
(referencing myCount, authorOptions, and me) so unauthenticated visitors won't
crash the component.

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.

Add "My Issues only" filter to the Issues page

1 participant