From b4e6e70ee105719c723e4422fb9399f31acf7096 Mon Sep 17 00:00:00 2001 From: Alan Daniel Date: Sat, 11 Apr 2026 18:34:44 -0400 Subject: [PATCH] Prefetch recent PR routes on overview and refetch tab queries in background On the overview page, preload detail routes for the 10 most recent authored PRs as soon as data loads so navigation is near-instant. In the webhook revalidation hook, use refetchType "all" so tab queries are refetched even when the tab isn't actively viewed. --- .../src/lib/use-github-revalidation.ts | 8 +++++-- .../dashboard/src/routes/_protected/index.tsx | 22 +++++++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/apps/dashboard/src/lib/use-github-revalidation.ts b/apps/dashboard/src/lib/use-github-revalidation.ts index cb7520a..0ad39c4 100644 --- a/apps/dashboard/src/lib/use-github-revalidation.ts +++ b/apps/dashboard/src/lib/use-github-revalidation.ts @@ -54,7 +54,9 @@ async function invalidatePullTabQueries( } await Promise.all( - queryKeys.map((queryKey) => queryClient.invalidateQueries({ queryKey })), + queryKeys.map((queryKey) => + queryClient.invalidateQueries({ queryKey, refetchType: "all" }), + ), ); } @@ -79,7 +81,9 @@ async function invalidateIssueTabQueries( } await Promise.all( - queryKeys.map((queryKey) => queryClient.invalidateQueries({ queryKey })), + queryKeys.map((queryKey) => + queryClient.invalidateQueries({ queryKey, refetchType: "all" }), + ), ); } diff --git a/apps/dashboard/src/routes/_protected/index.tsx b/apps/dashboard/src/routes/_protected/index.tsx index 27627f5..3f748b5 100644 --- a/apps/dashboard/src/routes/_protected/index.tsx +++ b/apps/dashboard/src/routes/_protected/index.tsx @@ -1,13 +1,14 @@ import { GitPullRequestIcon, IssuesIcon, ReviewsIcon } from "@diffkit/icons"; import { useQuery } from "@tanstack/react-query"; -import { createFileRoute, Link } from "@tanstack/react-router"; -import type { ComponentType } from "react"; +import { createFileRoute, Link, useRouter } from "@tanstack/react-router"; +import { type ComponentType, useEffect } from "react"; import { DashboardContentLoading } from "#/components/layouts/dashboard-content-loading"; import { PullRequestRow } from "#/components/pulls/pull-request-row"; import { githubMyIssuesQueryOptions, githubMyPullsQueryOptions, } from "#/lib/github.query"; +import { preloadRouteOnce } from "#/lib/route-preload"; import { buildSeo, formatPageTitle } from "#/lib/seo"; import { useHasMounted } from "#/lib/use-has-mounted"; @@ -36,6 +37,7 @@ function OverviewPage() { const { user } = Route.useRouteContext(); const scope = { userId: user.id }; const hasMounted = useHasMounted(); + const router = useRouter(); const pullsQuery = useQuery({ ...githubMyPullsQueryOptions(scope), enabled: hasMounted, @@ -45,6 +47,22 @@ function OverviewPage() { enabled: hasMounted, }); + // Prefetch detail routes for recent PRs in the background so + // navigating into a PR is near-instant even without hovering first. + const authoredPulls = pullsQuery.data?.authored; + useEffect(() => { + if (!authoredPulls) return; + const recent = authoredPulls.slice(0, 10); + void Promise.allSettled( + recent.map((pr) => + preloadRouteOnce( + router, + `/${pr.repository.owner}/${pr.repository.name}/pull/${pr.number}`, + ), + ), + ); + }, [authoredPulls, router]); + if (pullsQuery.error) throw pullsQuery.error; if (issuesQuery.error) throw issuesQuery.error;