Skip to content

Commit 00ce349

Browse files
committed
fix(graph-ui): scope typed-path picker refresh to Windows drive paths
The debounced folder-list refresh (and Enter-to-navigate) on the Repository path field now only fires for Windows drive paths (e.g. 'D:/'), where typing is the mechanism for switching drives. POSIX path navigation is left exactly as before. Add a regression test asserting a typed POSIX path does not trigger a re-browse. Signed-off-by: Zadak <rarepops@protonmail.com>
1 parent a201f8b commit 00ce349

2 files changed

Lines changed: 27 additions & 5 deletions

File tree

graph-ui/src/components/StatsTab.test.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,4 +180,24 @@ describe("StatsTab index modal", () => {
180180
expect(fetchMock).toHaveBeenCalledWith("/api/browse?path=C%3A%2F");
181181
});
182182
});
183+
184+
it("does not auto-refresh on POSIX when a path is typed", async () => {
185+
const fetchMock = mockProjectsFetch(); // browse returns POSIX path "/home/dev"
186+
187+
render(<StatsTab onSelectProject={() => {}} />);
188+
fireEvent.click(await screen.findByRole("button", { name: "Index your first repository" }));
189+
await screen.findByText("alpha"); // initial POSIX listing
190+
191+
const browseCalls = () =>
192+
fetchMock.mock.calls.filter((c) => String(c[0]).startsWith("/api/browse")).length;
193+
const before = browseCalls();
194+
195+
fireEvent.change(screen.getByLabelText("Repository path"), {
196+
target: { value: "/usr/local" },
197+
});
198+
199+
/* Wait past the debounce window; a POSIX path must NOT trigger a re-browse. */
200+
await new Promise((r) => setTimeout(r, 400));
201+
expect(browseCalls()).toBe(before);
202+
});
183203
});

graph-ui/src/components/StatsTab.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -207,12 +207,14 @@ function CreateIndexModal({ onClose, onCreated }: { onClose: () => void; onCreat
207207
useEffect(() => { browse(); }, [browse]);
208208
useEffect(() => { filterRef.current?.focus(); }, []);
209209

210-
/* When the user types a path directly into the Repository path field, refresh
211-
* the folder listing to match (debounced). Without this the breadcrumb and
212-
* path box updated but the directory list stayed stale — e.g. typing "D:/"
213-
* still showed the previous location's folders. */
210+
/* Windows only: when the user types a drive path into the Repository path
211+
* field, refresh the folder listing to match (debounced). On Windows, typing
212+
* is the way to switch drives, and without this the breadcrumb and path box
213+
* updated but the directory list stayed stale (e.g. typing "D:/" still showed
214+
* the previous drive's folders). POSIX navigation is left unchanged. */
214215
useEffect(() => {
215216
if (!currentPath || currentPath === lastBrowsedRef.current) return;
217+
if (!/^[A-Za-z]:/.test(currentPath.replace(/\\/g, "/"))) return;
216218
const id = setTimeout(() => { void browse(currentPath, { silent: true }); }, 350);
217219
return () => clearTimeout(id);
218220
}, [currentPath, browse]);
@@ -297,7 +299,7 @@ function CreateIndexModal({ onClose, onCreated }: { onClose: () => void; onCreat
297299
aria-label={t.index.repositoryPath}
298300
value={currentPath}
299301
onChange={(e) => setCurrentPath(e.target.value)}
300-
onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault(); void browse(currentPath); } }}
302+
onKeyDown={(e) => { if (e.key === "Enter" && /^[A-Za-z]:/.test(currentPath.replace(/\\/g, "/"))) { e.preventDefault(); void browse(currentPath); } }}
301303
className="w-full bg-white/[0.04] border border-white/[0.06] rounded-lg px-3 py-2 text-[12px] text-foreground font-mono outline-none focus:border-primary/40"
302304
/>
303305
</label>

0 commit comments

Comments
 (0)