From 3a454140960ab54907e444c32a24adeb9a5d12f3 Mon Sep 17 00:00:00 2001 From: Satya Patel Date: Thu, 7 May 2026 19:13:12 -0700 Subject: [PATCH] fix(desktop): restore v2 sidebar LOC indicator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #4160 swapped useDiffStats from imperative client.git.getStatus.query() to workspaceTrpc.git.getStatus.useQuery(). That broke the v2 dashboard sidebar: workspaceTrpc.Provider only mounts inside v2-workspace/$id, but the sidebar is a sibling of that Outlet — so its useQuery calls had no provider, and even with one couldn't fan out to workspaces on different hosts. Resolve hostUrl per-workspaceId, call the imperative client inside a react-query queryFn keyed on (hostUrl, workspaceId). Concurrent callers (tile + hover overlay for the same workspace) still dedup via the global QueryClient. staleTime: Infinity since git:changed is push-authoritative. --- .../host-service/useDiffStats/useDiffStats.ts | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) 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);