feat(FN-3477): document remotes tab commit refresh

Documents the remotes tab commit refresh behavior in the dashboard guide, adding one line to `docs/dashboard-guide.md`.

Fusion-Task-Id: FN-3477
This commit is contained in:
Fusion
2026-05-05 04:29:25 -07:00
committed by gsxdsm
parent 370391b772
commit f9dfab8961
3 changed files with 79 additions and 1 deletions

View File

@@ -1821,6 +1821,7 @@ function RemotesPanel({
const [remoteCommits, setRemoteCommits] = useState<GitCommit[]>([]);
const [loadingRemoteCommits, setLoadingRemoteCommits] = useState(false);
const [remoteCommitsError, setRemoteCommitsError] = useState<string | null>(null);
const remoteCommitsRequestIdRef = useRef(0);
// Derived state for selected remote
const selectedRemoteData = remotes.find((r) => r.name === selectedRemote);
@@ -1867,6 +1868,12 @@ function RemotesPanel({
}
}, [selectedRemote]);
// Refresh selected remote commits after successful sync operations.
useEffect(() => {
if (!selectedRemote || !lastRemoteResult) return;
loadRemoteCommits(selectedRemote);
}, [selectedRemote, lastRemoteResult]);
// Clear selected remote if it was removed from the list
useEffect(() => {
if (selectedRemote && !remotes.find((r) => r.name === selectedRemote)) {
@@ -1900,16 +1907,26 @@ function RemotesPanel({
};
const loadRemoteCommits = async (remoteName: string) => {
const requestId = remoteCommitsRequestIdRef.current + 1;
remoteCommitsRequestIdRef.current = requestId;
setLoadingRemoteCommits(true);
setRemoteCommitsError(null);
try {
const commits = await fetchRemoteCommits(remoteName, undefined, 10, projectId);
if (remoteCommitsRequestIdRef.current !== requestId) {
return;
}
setRemoteCommits(commits);
} catch (err) {
if (remoteCommitsRequestIdRef.current !== requestId) {
return;
}
setRemoteCommitsError(getErrorMessage(err) || "Failed to load remote commits");
setRemoteCommits([]);
} finally {
setLoadingRemoteCommits(false);
if (remoteCommitsRequestIdRef.current === requestId) {
setLoadingRemoteCommits(false);
}
}
};

View File

@@ -1928,6 +1928,66 @@ describe("GitManagerModal", () => {
});
});
it("refreshes recent remote commits after pull without reopening modal", async () => {
const user = userEvent.setup();
(fetchRemoteCommits as any)
.mockResolvedValueOnce([
{ hash: "rc1", shortHash: "rc1", message: "Remote commit before pull", author: "Dev", date: "2026-01-01T00:00:00Z", parents: [] },
])
.mockResolvedValueOnce([
{ hash: "rc2", shortHash: "rc2", message: "Remote commit after pull", author: "Dev", date: "2026-01-02T00:00:00Z", parents: [] },
]);
render(
<GitManagerModal isOpen={true} onClose={vi.fn()} tasks={mockTasks} addToast={mockAddToast} />
);
fireEvent.click(screen.getByRole("tab", { name: /remotes/i }));
await waitFor(() => {
expect(screen.getByText("Remote commit before pull")).toBeInTheDocument();
});
const syncCard = screen.getByTestId("remote-sync-card");
await user.click(within(syncCard).getByRole("button", { name: /pull/i }));
await waitFor(() => {
expect(pullBranch).toHaveBeenCalled();
expect(fetchRemoteCommits).toHaveBeenCalledTimes(2);
expect(screen.getByText("Remote commit after pull")).toBeInTheDocument();
expect(screen.queryByText("Remote commit before pull")).not.toBeInTheDocument();
});
});
it("refreshes recent remote commits after push without reopening modal", async () => {
const user = userEvent.setup();
(fetchRemoteCommits as any)
.mockResolvedValueOnce([
{ hash: "rc10", shortHash: "rc10", message: "Remote commit before push", author: "Dev", date: "2026-01-01T00:00:00Z", parents: [] },
])
.mockResolvedValueOnce([
{ hash: "rc11", shortHash: "rc11", message: "Remote commit after push", author: "Dev", date: "2026-01-02T00:00:00Z", parents: [] },
]);
render(
<GitManagerModal isOpen={true} onClose={vi.fn()} tasks={mockTasks} addToast={mockAddToast} />
);
fireEvent.click(screen.getByRole("tab", { name: /remotes/i }));
await waitFor(() => {
expect(screen.getByText("Remote commit before push")).toBeInTheDocument();
});
const syncCard = screen.getByTestId("remote-sync-card");
await user.click(within(syncCard).getByRole("button", { name: /push/i }));
await waitFor(() => {
expect(pushBranch).toHaveBeenCalled();
expect(fetchRemoteCommits).toHaveBeenCalledTimes(2);
expect(screen.getByText("Remote commit after push")).toBeInTheDocument();
expect(screen.queryByText("Remote commit before push")).not.toBeInTheDocument();
});
});
it("does not show remote commits section when no remotes configured", async () => {
(fetchGitRemotesDetailed as any).mockResolvedValue([]);