-
Notifications
You must be signed in to change notification settings - Fork 960
fix(desktop): restore v2 sidebar LOC indicator #4222
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -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, | ||||||||||||||||||||
| }); | ||||||||||||||||||||
|
Comment on lines
+29
to
+31
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Consider adding Prompt To Fix With AIThis is a comment left during a code review.
Path: apps/desktop/src/renderer/hooks/host-service/useDiffStats/useDiffStats.ts
Line: 29-31
Comment:
**Stale indicator if `git:changed` event is missed on reconnect**
`staleTime: Number.POSITIVE_INFINITY` + `refetchOnWindowFocus: false` means the LOC chip updates *only* when a `git:changed` WebSocket event is received. If the event bus connection drops and reconnects, any file edits made during the gap are silently invisible — the chip keeps showing the pre-disconnect value until the user makes another change that triggers a fresh push event. In the previous `staleTime: 0` regime a component remount (e.g., after a tab switch) would naturally re-prime the cache; that safety net is now gone.
Consider adding `refetchOnReconnect: true` (verify it fires for the non-window WebSocket path) or having the event bus emit a synthetic `git:changed` after reconnect so the existing invalidation path kicks in.
How can I resolve this? If you propose a fix, please make it concise. |
||||||||||||||||||||
|
|
||||||||||||||||||||
| const invalidate = useCallback(() => { | ||||||||||||||||||||
| void utils.git.getStatus.invalidate({ workspaceId }); | ||||||||||||||||||||
| }, [utils, workspaceId]); | ||||||||||||||||||||
| void queryClient.invalidateQueries({ queryKey }); | ||||||||||||||||||||
| }, [queryClient, queryKey]); | ||||||||||||||||||||
|
Comment on lines
33
to
+35
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Prompt To Fix With AIThis is a comment left during a code review.
Path: apps/desktop/src/renderer/hooks/host-service/useDiffStats/useDiffStats.ts
Line: 33-35
Comment:
The `invalidate` callback captures `queryKey` at the time it was last memoized. When `hostUrl` is still `null` (the workspace host is loading), `queryKey` is `["diff-stats", null, workspaceId]` and any `git:changed` event fired in that window calls `invalidateQueries` with that null key — targeting a query that was never enabled and has no cached data, so the invalidation is silently dropped. Adding an early-return guard makes the intent explicit and avoids the vacuous call.
```suggestion
const invalidate = useCallback(() => {
if (!hostUrl) return;
void queryClient.invalidateQueries({ queryKey });
}, [queryClient, queryKey, hostUrl]);
```
How can I resolve this? If you propose a fix, please make it concise. |
||||||||||||||||||||
|
|
||||||||||||||||||||
| useWorkspaceEvent("git:changed", workspaceId, invalidate); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| return useMemo<DiffStats | null>(() => { | ||||||||||||||||||||
| if (!status) return null; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Deduplicate by path — a file can appear in multiple categories. | ||||||||||||||||||||
| const byPath = new Map<string, { additions: number; deletions: number }>(); | ||||||||||||||||||||
| for (const file of status.againstBase) byPath.set(file.path, file); | ||||||||||||||||||||
| for (const file of status.staged) byPath.set(file.path, file); | ||||||||||||||||||||
|
|
||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
staleTime: POSITIVE_INFINITYcreates a silent stale-data risk on first mount.With
git:changedas the sole refresh trigger, any change that occurs between component mount and listener registration (useWorkspaceEventsubscribing) will leave the UI permanently stale for that session — no background refetch or window-focus refetch will rescue it. The PR notes this is intentional ("push-authoritative"), but it's worth confirming the event subscription is guaranteed to be in place before any relevantgit:changedevents can fire.If there's a realistic race on initial mount (e.g., workspace git state changes during the first render cycle), consider a short
staleTime(e.g., 30 s) or a conservativegcTimepaired with an initialrefetchOnMount: trueto ensure the first load is always fresh, while still avoiding redundant window-focus refetches.🤖 Prompt for AI Agents