Skip to content

[BUG] Miner PRs table: Score sort broken for open PRs, Repository column unsortable #276

@eureka0928

Description

@eureka0928

Description

On the Miner Details page's Pull Requests table (/miners/details?githubId=<id>&tab=pull-requests), the Score column's sort is broken for open PRs and the Repository column is not sortable at all.

  • Score sort sorts by a different field than the cell displays. The cell renders collateralScore for open unmerged PRs, score for merged PRs, and - for closed-unmerged. The sort comparator unconditionally reads pr.score, so every open PR is treated as score = 0 and clicking the Score header does not reorder the open-PR rows.
  • Repository column has no sort control. The header is a plain <TableCell>Repository</TableCell> with no <TableSortLabel>, so users cannot group the table by repo.

Steps to Reproduce

  1. Open https://gittensor.io/miners/details?githubId=42954461&tab=pull-requests (any miner with a mix of merged and open PRs reproduces it — this one has 17 open PRs with non-zero collateral, making the bug visually obvious).
  2. Click the Score column header one or more times. Observe the open-PR rows (the ones with a "Collateral" sublabel under the value).
  3. Look at the Repository column header and try to click it.

Expected Behavior

  1. Clicking Score should reorder the rows by the value the cell actually displays — i.e., by collateralScore for open PRs and score for merged PRs. Highest first on the first click, lowest first after a second click.
  2. The Repository column header should be a sortable control like the other columns. Clicking it should group rows alphabetically by owner/repo (ascending on first click, descending on second), with a deterministic tiebreaker within a single repo.

Actual Behavior

  1. Clicking Score leaves the open-PR rows in whatever order the API returned. Verified against miner 42954461 via the test API: all 17 open PRs have pr.score = "0.000000" while their collateralScore ranges from 0.001 to 0.370. The comparator sees 17 zeros and cannot order them, so the displayed collateral column appears to ignore the sort click.
  2. The Repository column header is static text. There is no sort indicator, no hover affordance, and clicking it does nothing. The only way to group by repo today is a substring search, which misses casing differences and picks up partial matches.

Environment

  • Browser: reproduced on latest Chrome and Firefox (not browser-specific — the bug is in the sort comparator, not the rendering)
  • OS: any
  • URL: https://gittensor.io/miners/details?githubId=42954461&tab=pull-requests
  • Branch: reproduced on both main and test as of 2026-04-15

Additional Context

Videos

Before: https://github.com/user-attachments/assets/49bceb35-5d15-4e45-be55-096c3185fa98

Clicking the Score header on miner 42954461 — the open-PR rows (with the "Collateral" sublabel) stay in the same order across clicks because the comparator reads pr.score = 0 for all of them. The Repository header is not clickable.

After: https://github.com/user-attachments/assets/b26870e1-8835-4233-bdbe-61b91bf6b6bf

Same miner, same clicks. Score now reorders open-PR rows by their displayed collateral value (highest-first on the first click, lowest-first after toggling). Repository is a sortable header that groups rows by owner/repo.

Root cause

src/components/miners/MinerPRsTable.tsx in the sortedPRs useMemo:

case 'score':
  cmp = parseFloat(a.score || '0') - parseFloat(b.score || '0');
  break;

Meanwhile the Score cell's render chain further down in the same file reads:

pr.prState === 'CLOSED' && !pr.mergedAt
  ? '-'
  : !pr.mergedAt && pr.collateralScore
    ? parseFloat(pr.collateralScore).toFixed(4)   // "Collateral" label
    : parseFloat(pr.score).toFixed(4)

The sort comparator and the renderer read different fields. For merged PRs they agree. For open PRs with collateral they diverge, and all open PRs collapse to the same sort key.

The Repository header:

<TableCell sx={{ ...headerCellStyle, width: '25%' }}>
  Repository
</TableCell>

No <TableSortLabel>, no click handler, no 'repository' entry in the PrSortField type.

Proposed fix

  1. Extract a getEffectiveScore(pr) helper that mirrors the render fallback exactly — CLOSED && !mergedAt → 0, !mergedAt && collateralScore → parseFloat(collateralScore), else parseFloat(score). Use it in the 'score' case so the sort key matches the displayed value.
  2. Add 'repository' to PrSortField and implement the comparator with a.repository.localeCompare(b.repository), falling back to a.pullRequestNumber - b.pullRequestNumber as a deterministic tiebreaker within a single repo.
  3. Introduce a DEFAULT_SORT_DIR: Record<PrSortField, SortDir> map so each column has a self-documenting natural direction — string columns ascending, numeric/date columns descending — and handleSort reads from it instead of branching on the field name. Keeps future sortable columns (Title, Author, etc.) a one-line addition.
  4. Wrap the Repository header in <TableSortLabel>, consistent with the PR #, +/-, Score, and Date headers. Idle-state direction comes from DEFAULT_SORT_DIR.repository.

Scope

  • Frontend only, no API or data-shape changes.
  • Single file: src/components/miners/MinerPRsTable.tsx (~40 lines added, ~4 removed).
  • No visual regression for currently-working columns (PR #, +/-, Date).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions