diff --git a/apps/desktop/src/renderer/hooks/host-service/useDiffStats/useDiffStats.ts b/apps/desktop/src/renderer/hooks/host-service/useDiffStats/useDiffStats.ts index 4d23f60f135..1fe9dcc5f39 100644 --- a/apps/desktop/src/renderer/hooks/host-service/useDiffStats/useDiffStats.ts +++ b/apps/desktop/src/renderer/hooks/host-service/useDiffStats/useDiffStats.ts @@ -1,42 +1,44 @@ -import { workspaceTrpc } from "@superset/workspace-client"; +import { useQuery, useQueryClient } from "@tanstack/react-query"; import { useCallback, useMemo } from "react"; +import { getHostServiceClientByUrl } from "renderer/lib/host-service-client"; import { useWorkspaceEvent } from "../useWorkspaceEvent"; +import { useWorkspaceHostUrl } from "../useWorkspaceHostUrl"; export interface DiffStats { additions: number; deletions: number; } -/** - * Diff stats for a single workspace, derived from the shared `git.getStatus` - * query cache. Subscribes to `git:changed` and invalidates the query — React - * Query collapses concurrent invalidations from sibling consumers (e.g. - * `useGitStatus`, multiple sidebar tiles) into a single refetch. - */ export function useDiffStats(workspaceId: string): DiffStats | null { - const utils = workspaceTrpc.useUtils(); - const { data: status } = workspaceTrpc.git.getStatus.useQuery( - { workspaceId }, - { - enabled: Boolean(workspaceId), - // Match the pre-RQ behavior: only update on `git:changed`, never - // on focus. Multiple sidebar tiles each have their own query key, - // so focus refetch would re-fan out the very work this hook is - // supposed to consolidate. - refetchOnWindowFocus: false, - }, + const hostUrl = useWorkspaceHostUrl(workspaceId); + const queryClient = useQueryClient(); + const queryKey = useMemo( + () => ["diff-stats", hostUrl, workspaceId] as const, + [hostUrl, workspaceId], ); + const { data: status } = useQuery({ + queryKey, + enabled: Boolean(workspaceId) && Boolean(hostUrl), + queryFn: () => { + if (!hostUrl) return null; + return getHostServiceClientByUrl(hostUrl).git.getStatus.query({ + workspaceId, + }); + }, + refetchOnWindowFocus: false, + staleTime: Number.POSITIVE_INFINITY, + }); + const invalidate = useCallback(() => { - void utils.git.getStatus.invalidate({ workspaceId }); - }, [utils, workspaceId]); + void queryClient.invalidateQueries({ queryKey }); + }, [queryClient, queryKey]); useWorkspaceEvent("git:changed", workspaceId, invalidate); return useMemo(() => { if (!status) return null; - // Deduplicate by path — a file can appear in multiple categories. const byPath = new Map(); for (const file of status.againstBase) byPath.set(file.path, file); for (const file of status.staged) byPath.set(file.path, file);