Add auto-refresh polling across all admin and jury pages
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m35s
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m35s
- Round detail page: 15s for live data (projects, assignments, scores, workload), 30s for config, 60s for static data - Filtering dashboard: 15s for results/stats, 30s for rules (job status already 2s) - Project states table: 15s polling - Coverage report: 15s polling - Jury round page: 30s for assignments and round data - Deliberation session: 10s polling for live vote updates - Admin dashboard: 30s for stats Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -253,7 +253,7 @@ function getActionIcon(action: string) {
|
||||
export function DashboardContent({ editionId, sessionName }: DashboardContentProps) {
|
||||
const { data, isLoading, error } = trpc.dashboard.getStats.useQuery(
|
||||
{ editionId },
|
||||
{ enabled: !!editionId, retry: 1 }
|
||||
{ enabled: !!editionId, retry: 1, refetchInterval: 30_000 }
|
||||
)
|
||||
|
||||
if (isLoading) {
|
||||
|
||||
@@ -151,26 +151,35 @@ export default function RoundDetailPage() {
|
||||
const utils = trpc.useUtils()
|
||||
|
||||
// ── Core data queries ──────────────────────────────────────────────────
|
||||
const { data: round, isLoading } = trpc.round.getById.useQuery({ id: roundId })
|
||||
const { data: projectStates } = trpc.roundEngine.getProjectStates.useQuery({ roundId })
|
||||
const { data: round, isLoading } = trpc.round.getById.useQuery(
|
||||
{ id: roundId },
|
||||
{ refetchInterval: 30_000 },
|
||||
)
|
||||
const { data: projectStates } = trpc.roundEngine.getProjectStates.useQuery(
|
||||
{ roundId },
|
||||
{ refetchInterval: 15_000 },
|
||||
)
|
||||
|
||||
const competitionId = round?.competitionId ?? ''
|
||||
|
||||
const { data: juryGroups } = trpc.juryGroup.list.useQuery(
|
||||
{ competitionId },
|
||||
{ enabled: !!competitionId },
|
||||
{ enabled: !!competitionId, refetchInterval: 30_000 },
|
||||
)
|
||||
const { data: fileRequirements } = trpc.file.listRequirements.useQuery(
|
||||
{ roundId },
|
||||
{ refetchInterval: 30_000 },
|
||||
)
|
||||
const { data: fileRequirements } = trpc.file.listRequirements.useQuery({ roundId })
|
||||
|
||||
// Fetch awards linked to this round
|
||||
const { data: competition } = trpc.competition.getById.useQuery(
|
||||
{ id: competitionId },
|
||||
{ enabled: !!competitionId },
|
||||
{ enabled: !!competitionId, refetchInterval: 60_000 },
|
||||
)
|
||||
const programId = competition?.programId
|
||||
const { data: awards } = trpc.specialAward.list.useQuery(
|
||||
{ programId: programId! },
|
||||
{ enabled: !!programId },
|
||||
{ enabled: !!programId, refetchInterval: 60_000 },
|
||||
)
|
||||
const roundAwards = awards?.filter((a) => a.evaluationRoundId === roundId) ?? []
|
||||
|
||||
@@ -1184,6 +1193,7 @@ export default function RoundDetailPage() {
|
||||
function RoundUnassignedQueue({ roundId }: { roundId: string }) {
|
||||
const { data: unassigned, isLoading } = trpc.roundAssignment.unassignedQueue.useQuery(
|
||||
{ roundId, requiredReviews: 3 },
|
||||
{ refetchInterval: 15_000 },
|
||||
)
|
||||
|
||||
return (
|
||||
@@ -1235,7 +1245,10 @@ function RoundUnassignedQueue({ roundId }: { roundId: string }) {
|
||||
// ── Jury Progress Table ──────────────────────────────────────────────────
|
||||
|
||||
function JuryProgressTable({ roundId }: { roundId: string }) {
|
||||
const { data: workload, isLoading } = trpc.analytics.getJurorWorkload.useQuery({ roundId })
|
||||
const { data: workload, isLoading } = trpc.analytics.getJurorWorkload.useQuery(
|
||||
{ roundId },
|
||||
{ refetchInterval: 15_000 },
|
||||
)
|
||||
|
||||
return (
|
||||
<Card>
|
||||
@@ -1291,7 +1304,10 @@ function JuryProgressTable({ roundId }: { roundId: string }) {
|
||||
// ── Score Distribution ───────────────────────────────────────────────────
|
||||
|
||||
function ScoreDistribution({ roundId }: { roundId: string }) {
|
||||
const { data: dist, isLoading } = trpc.analytics.getRoundScoreDistribution.useQuery({ roundId })
|
||||
const { data: dist, isLoading } = trpc.analytics.getRoundScoreDistribution.useQuery(
|
||||
{ roundId },
|
||||
{ refetchInterval: 15_000 },
|
||||
)
|
||||
|
||||
const maxCount = useMemo(() =>
|
||||
dist ? Math.max(...dist.globalDistribution.map((b) => b.count), 1) : 1,
|
||||
@@ -1428,7 +1444,10 @@ function IndividualAssignmentsTable({ roundId }: { roundId: string }) {
|
||||
const [newProjectId, setNewProjectId] = useState('')
|
||||
|
||||
const utils = trpc.useUtils()
|
||||
const { data: assignments, isLoading } = trpc.assignment.listByStage.useQuery({ roundId })
|
||||
const { data: assignments, isLoading } = trpc.assignment.listByStage.useQuery(
|
||||
{ roundId },
|
||||
{ refetchInterval: 15_000 },
|
||||
)
|
||||
|
||||
const deleteMutation = trpc.assignment.delete.useMutation({
|
||||
onSuccess: () => {
|
||||
@@ -1573,7 +1592,10 @@ function EvaluationCriteriaEditor({ roundId }: { roundId: string }) {
|
||||
}>>([])
|
||||
|
||||
const utils = trpc.useUtils()
|
||||
const { data: form, isLoading } = trpc.evaluation.getForm.useQuery({ roundId })
|
||||
const { data: form, isLoading } = trpc.evaluation.getForm.useQuery(
|
||||
{ roundId },
|
||||
{ refetchInterval: 30_000 },
|
||||
)
|
||||
|
||||
const upsertMutation = trpc.evaluation.upsertForm.useMutation({
|
||||
onSuccess: () => {
|
||||
|
||||
Reference in New Issue
Block a user