feat: show active ranking score on each list row
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m20s

Each ranking row now displays a small chip with the score that's
currently driving the rank — the juror-balanced average when the
round's useBalancedRanking toggle is on, the raw juror average when
it's off. The chip is labeled 'Bal' or 'Raw' so the source is
unambiguous. Per-juror score pills stay alongside; full Raw +
Balanced detail still lives in the side panel.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matt
2026-04-27 13:54:13 +02:00
parent 9db8312b96
commit d0e7bfd60a

View File

@@ -84,6 +84,9 @@ type SortableProjectRowProps = {
entry: (RankedProjectEntry & { originalIndex?: number }) | undefined
projectInfo: ProjectInfo | undefined
jurorScores: JurorScore[] | undefined
rawAverage: number | null
balancedAverage: number | null
useBalanced: boolean
onSelect: () => void
isSelected: boolean
originalRank: number | undefined // from snapshotOrder — always in sync with localOrder
@@ -97,6 +100,9 @@ function SortableProjectRow({
entry,
projectInfo,
jurorScores,
rawAverage,
balancedAverage,
useBalanced,
onSelect,
isSelected,
originalRank,
@@ -195,12 +201,24 @@ function SortableProjectRow({
</span>
))}
</div>
) : entry?.avgGlobalScore !== null && entry?.avgGlobalScore !== undefined ? (
<span className="text-xs text-muted-foreground">
Avg {entry.avgGlobalScore.toFixed(2)}
</span>
) : null}
{/* Active score chip (balanced if toggle on, otherwise raw) */}
{(() => {
const active = useBalanced && balancedAverage != null ? balancedAverage : rawAverage
if (active == null) return null
const label = useBalanced && balancedAverage != null ? 'Bal' : 'Raw'
return (
<span
className="inline-flex items-baseline gap-1 rounded-md border bg-muted/50 px-2 py-0.5 text-xs tabular-nums"
title={`${label === 'Bal' ? 'Juror-balanced average' : 'Raw juror average'} (used for ranking)`}
>
<span className="text-[10px] uppercase tracking-wide text-muted-foreground">{label}</span>
<span className="font-semibold">{active.toFixed(2)}</span>
</span>
)
})()}
{/* Advance decision indicator */}
<div className={cn(
'inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium',
@@ -978,6 +996,9 @@ export function RankingDashboard({ competitionId: _competitionId, roundId }: Ran
entry={rankingMap.get(projectId)}
projectInfo={projectInfoMap.get(projectId)}
jurorScores={evalScores?.byProject[projectId]}
rawAverage={evalScores?.balanced[projectId]?.rawAverage ?? null}
balancedAverage={evalScores?.balanced[projectId]?.balancedAverage ?? null}
useBalanced={useBalanced}
onSelect={() => setSelectedProjectId(projectId)}
isSelected={selectedProjectId === projectId}
originalRank={hasReorders ? snapshotOrder[projectId] : undefined}