feat: poll evaluation scores every 30s and re-sort live
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m32s
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m32s
The ranking dashboard now refetches roundEvaluationScores every 30 seconds. When a juror submits a new evaluation, the next refetch updates the raw and balanced averages, and the existing re-sort effect (now also keyed on snapshot + evalScores, not just the toggle) re-orders the list in place. Manual reorders persisted on the snapshot still take precedence — admins who have dragged rows aren't overruled by score updates. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -310,6 +310,7 @@ export function RankingDashboard({ competitionId: _competitionId, roundId }: Ran
|
|||||||
|
|
||||||
const { data: evalScores } = trpc.ranking.roundEvaluationScores.useQuery(
|
const { data: evalScores } = trpc.ranking.roundEvaluationScores.useQuery(
|
||||||
{ roundId },
|
{ roundId },
|
||||||
|
{ refetchInterval: 30_000 },
|
||||||
)
|
)
|
||||||
|
|
||||||
const { data: evalForm } = trpc.evaluation.getStageForm.useQuery(
|
const { data: evalForm } = trpc.evaluation.getStageForm.useQuery(
|
||||||
@@ -464,9 +465,12 @@ export function RankingDashboard({ competitionId: _competitionId, roundId }: Ran
|
|||||||
}
|
}
|
||||||
}, [snapshot, evalScores])
|
}, [snapshot, evalScores])
|
||||||
|
|
||||||
// ─── Re-sort on toggle flip (after init) ─────────────────────────────────
|
// ─── Re-sort when toggle flips OR scores refetch (after init) ────────────
|
||||||
// Only resorts when no server-side manual reorder is pinned for the snapshot;
|
// Only resorts when no server-side manual reorder is pinned for the snapshot;
|
||||||
// persisted manual reorders always win regardless of the score being used.
|
// persisted manual reorders always win regardless of the score being used.
|
||||||
|
// The 30-second polling on roundEvaluationScores feeds this effect — when a
|
||||||
|
// juror submits a new evaluation, the next refetch picks it up, balanced/raw
|
||||||
|
// averages update, and the list re-sorts in place.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!initialized.current || !snapshot || !evalScores) return
|
if (!initialized.current || !snapshot || !evalScores) return
|
||||||
const reorders = (snapshot.reordersJson as Array<{
|
const reorders = (snapshot.reordersJson as Array<{
|
||||||
@@ -502,10 +506,7 @@ export function RankingDashboard({ competitionId: _competitionId, roundId }: Ran
|
|||||||
STARTUP: sortedStartup.map((r) => r.projectId),
|
STARTUP: sortedStartup.map((r) => r.projectId),
|
||||||
BUSINESS_CONCEPT: sortedConcept.map((r) => r.projectId),
|
BUSINESS_CONCEPT: sortedConcept.map((r) => r.projectId),
|
||||||
})
|
})
|
||||||
// Eslint disable: snapshot/evalScores are read but the resort should only
|
}, [useBalanced, evalScores, snapshot])
|
||||||
// run on toggle flip, not on every snapshot/scores refetch.
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [useBalanced])
|
|
||||||
|
|
||||||
// ─── numericCriteria from eval form ─────────────────────────────────────
|
// ─── numericCriteria from eval form ─────────────────────────────────────
|
||||||
const numericCriteria = useMemo(() => {
|
const numericCriteria = useMemo(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user