fix(FN-1721): scope GitHub import remotes to project - #1722
Conversation
Pass the active projectId when the GitHub import modal detects remotes so multi-project dashboards do not show a false no-remotes state. Ignore stale remote responses when projectId changes while the modal remains open. References: #1721
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Ready to review this PR? Stage has broken it down into 4 individual chapters for you:
Chapters generated by Stage for commit 5e0e9c0 on Jun 22, 2026 4:36pm UTC. |
Map the shared dashboard ViewHeader module in Vite, Vitest, and app TS paths so bundled plugin dashboard views resolve the host component during PR build/typecheck. References: #1721
Greptile SummaryThis PR fixes
Confidence Score: 5/5Safe to merge. The changes are narrowly scoped to remote detection in the GitHub import modal and alias additions to build/typecheck configs with no risk to other surfaces. The core logic change (passing projectId + stale-response guard) is straightforward and backed by two targeted regression tests — one verifying the forwarding, one exercising the race condition. The missing projectId dependency on handleImport was a real pre-existing stale-closure bug that is now closed. Alias additions are additive-only and consistent across all four config files. No state-management surprises, no unguarded edge cases in the new async flow. No files require special attention. The stale-response guard in GitHubImportModal.tsx is worth a read to verify the cancelled + requestId dual-guard reasoning, but both mechanisms agree and the test covers the scenario end-to-end. Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant UI as GitHubImportModal
participant Ref as remoteLoadRequestIdRef
participant API as fetchGitRemotes (API)
Note over UI: isOpen=true, projectId=A
UI->>Ref: "increment → requestId=1"
UI->>API: fetchGitRemotes("project-a")
Note over UI: projectId changes to B (modal stays open)
UI->>UI: "cleanup: cancelled_A=true"
UI->>Ref: "increment → requestId=2"
UI->>API: fetchGitRemotes("project-b")
API-->>UI: resolve project-b remotes
UI->>UI: "guard passes (requestId=2, !cancelled_B)"
UI->>UI: setRemotes(project-b remotes)
API-->>UI: resolve project-a remotes (stale)
UI->>UI: "guard fires (cancelled_A=true → skip)"
Note over UI: project-a data discarded ✓
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant UI as GitHubImportModal
participant Ref as remoteLoadRequestIdRef
participant API as fetchGitRemotes (API)
Note over UI: isOpen=true, projectId=A
UI->>Ref: "increment → requestId=1"
UI->>API: fetchGitRemotes("project-a")
Note over UI: projectId changes to B (modal stays open)
UI->>UI: "cleanup: cancelled_A=true"
UI->>Ref: "increment → requestId=2"
UI->>API: fetchGitRemotes("project-b")
API-->>UI: resolve project-b remotes
UI->>UI: "guard passes (requestId=2, !cancelled_B)"
UI->>UI: setRemotes(project-b remotes)
API-->>UI: resolve project-a remotes (stale)
UI->>UI: "guard fires (cancelled_A=true → skip)"
Note over UI: project-a data discarded ✓
Reviews (1): Last reviewed commit: "fix(FN-1721): expose ViewHeader to dashb..." | Re-trigger Greptile |
Summary
Fixes #1721.
The Import from GitHub modal now passes the active
projectIdinto remote detection, so/api/git/remotesis queried for the selected project instead of falling back to the dashboard process context. This prevents the dialog from showing "No GitHub remotes detected" when a project has configured GitHub remotes.The remote-loading effect also ignores stale responses when the active project changes while the modal remains open, so an older project's remotes cannot overwrite the current project's selection.
This PR also exposes the shared dashboard
ViewHeaderalias to Vite/Vitest/app TypeScript config so bundled plugin dashboard views resolve the host component in CI.Root Cause
GitHubImportModalcalledfetchGitRemotes()withoutprojectId. In multi-project mode the backend returns an empty remote list without project scope, causing the modal to display the no-remotes state despite valid GitHub remotes.The CI failure was caused by
plugins/fusion-plugin-compound-engineering/src/dashboard/CompoundEngineeringView.tsximporting@fusion/dashboard/app/components/ViewHeaderwhile the dashboard build/test aliases only exposedTaskCard.Validation
Local:
pnpm --filter @fusion/dashboard exec vitest run --project dashboard-app-quality-backfill --silent=passed-only --reporter=dot --exclude '**/build-output.test.ts' app/components/__tests__/GitHubImportModal.test.tsxpnpm exec eslint packages/dashboard/app/components/GitHubImportModal.tsx packages/dashboard/app/components/__tests__/GitHubImportModal.test.tsx packages/dashboard/vite.config.ts packages/dashboard/vitest.config.tspnpm --filter @fusion/dashboard typecheckpnpm --filter @fusion/dashboard buildCI:
Summary by CodeRabbit
Release Notes
Bug Fixes
Tests