diff --git a/.changeset/fn-8017-hide-imported-toggle.md b/.changeset/fn-8017-hide-imported-toggle.md
new file mode 100644
index 0000000000..107f8e47b9
--- /dev/null
+++ b/.changeset/fn-8017-hide-imported-toggle.md
@@ -0,0 +1,7 @@
+---
+"@runfusion/fusion": minor
+---
+
+summary: Add a Hide imported toggle that filters imported issues, PRs, and GitLab items from Import Tasks.
+category: feature
+dev: GitHubImportModal renders a persisted per-project hideImported toggle in the list-pane header (and the GitLab toolbar/header); when on, imported rows (importedUrls predicate) are excluded from the issues/pulls/GitLab render sets while the "{n} imported" count still reflects the full fetched set, with a dedicated all-imported empty state. Toggle persists via GitHubImportPersistedState.hideImported.
diff --git a/docs/dashboard-guide.md b/docs/dashboard-guide.md
index 54ac5ea0d5..5ef69ee138 100644
--- a/docs/dashboard-guide.md
+++ b/docs/dashboard-guide.md
@@ -302,13 +302,13 @@ Use Import Tasks on desktop/tablet:
2. Choose or enter a repository (`owner/repo`). If Git remotes are detected, use the remote selector.
Expected outcome: Fusion loads import candidates for the selected repository and shows repository/load state feedback.
3. Stay on **Issues** or switch to **Pull Requests**, then optionally enter issue label filters before loading results.
- Expected outcome: the list pane shows matching open issues or pull requests and marks entries that already exist on the board. After a successful GitHub or GitLab import, the source row is marked **Imported** and made unavailable immediately, without waiting for the board list to refresh.
+ Expected outcome: the list pane shows matching open issues or pull requests and marks entries that already exist on the board. Use **Hide imported** beside the imported count to remove those unavailable rows from the current Issues, Pull Requests, or GitLab list; turning it off restores the greyed **Imported** rows. After a successful GitHub or GitLab import, the source row is marked **Imported** and made unavailable immediately, without waiting for the board list to refresh.
4. Select an issue or pull request row.
Expected outcome: the full-width candidate list stays visible while its title, source link, body, labels or PR metadata, and import controls open in a draggable and resizable detail window. On mobile, that detail is a full-screen sheet. When selected title/body content is in another language, the detail offers **Translate**, **Show original** / **Show translation**, and **Dismiss**; translation is display-only.
5. Select the import action in the detail window.
Expected outcome: Fusion creates a task (or review task for a pull request), preserves GitHub provenance/tracking metadata, closes the detail window, and returns to the list.
-Leaving and returning to **Import Tasks** (for example switching to Board and back) restores the prior context for the current project — provider (GitHub/GitLab), active Issues/PRs tab, label filter, selected repository/remote, GitLab project/group inputs, and the previously selected issue/PR — instead of resetting to defaults. When GitLab integration is disabled in Settings, the GitLab provider tab is hidden and any restored GitLab provider preference opens on GitHub instead; saved GitLab URLs and tokens remain configured. The restored selection re-validates against the freshly reloaded list; a selection that no longer exists (e.g. the issue was closed upstream) clears gracefully rather than showing a stuck or empty preview. First-time opens with no prior state keep the existing default-remote auto-detect behavior. State is scoped per project and does not leak across projects.
+Leaving and returning to **Import Tasks** (for example switching to Board and back) restores the prior context for the current project — provider (GitHub/GitLab), active Issues/PRs tab, label filter, selected repository/remote, GitLab project/group inputs, the **Hide imported** preference, and the previously selected issue/PR — instead of resetting to defaults. When GitLab integration is disabled in Settings, the GitLab provider tab is hidden and any restored GitLab provider preference opens on GitHub instead; saved GitLab URLs and tokens remain configured. The restored selection re-validates against the freshly reloaded list; a selection that no longer exists (e.g. the issue was closed upstream) clears gracefully rather than showing a stuck or empty preview. First-time opens with no prior state keep the existing default-remote auto-detect behavior. State is scoped per project and does not leak across projects.
Use GitHub import on mobile:
diff --git a/packages/dashboard/app/components/GitHubImportModal.css b/packages/dashboard/app/components/GitHubImportModal.css
index 83a0b002ca..ca1a5cc309 100644
--- a/packages/dashboard/app/components/GitHubImportModal.css
+++ b/packages/dashboard/app/components/GitHubImportModal.css
@@ -565,6 +565,26 @@ The Import Tasks sub-header tab bar should match the Artifacts view's button bar
background: var(--surface);
}
+/*
+FNXC:GitHubImport 2026-07-15-16:30:
+Hide imported must remain a compact, reachable control beside loaded-result metadata and within the GitLab toolbar, including
+when either layout wraps on mobile. Token-based spacing keeps it consistent with the surrounding import controls.
+*/
+.github-import-hide-imported {
+ display: inline-flex;
+ align-items: center;
+ gap: var(--space-xs);
+ color: var(--text-muted);
+ font-size: 12px;
+ white-space: nowrap;
+ cursor: pointer;
+}
+
+.github-import-hide-imported input {
+ margin: 0;
+ accent-color: var(--accent);
+}
+
.github-import-state {
display: flex;
align-items: flex-start;
@@ -1246,6 +1266,7 @@ Across the thread: a top filter (All/Human/Bot) and prev/next chevrons live in t
justify-content: flex-start;
}
+
.issue-item {
flex-wrap: wrap;
min-height: 36px;
diff --git a/packages/dashboard/app/components/GitHubImportModal.tsx b/packages/dashboard/app/components/GitHubImportModal.tsx
index 0fa310185a..296668462d 100644
--- a/packages/dashboard/app/components/GitHubImportModal.tsx
+++ b/packages/dashboard/app/components/GitHubImportModal.tsx
@@ -429,6 +429,13 @@ export function GitHubImportModal({ isOpen, onClose, onImport, tasks, projectId,
// Gates the persist-on-change effect until the mount hydration effect has applied its (possibly restored) values to
// state, so the FIRST commit's still-default state is never written over a real persisted value.
const [readyToPersistImportState, setReadyToPersistImportState] = useState(false);
+ const [hideImported, setHideImported] = useState(false);
+
+ /*
+ FNXC:GitHubImport 2026-07-15-16:30:
+ The Hide imported control is a view-only filter over already-imported candidates. Persist it per project with the other
+ cheap Import Tasks preferences so navigation preserves the operator's decluttering choice without retaining fetched lists.
+ */
/*
FNXC:GitHubImport 2026-07-15-15:30:
@@ -493,6 +500,7 @@ export function GitHubImportModal({ isOpen, onClose, onImport, tasks, projectId,
setOwner("");
setRepo("");
setLabels(persisted?.labels ?? "");
+ setHideImported(persisted?.hideImported ?? false);
setProvider(persisted?.provider ?? "github");
setGitlabResource(persisted?.gitlabResource ?? "project_issue");
setGitlabProject(persisted?.gitlabProject ?? "");
@@ -832,6 +840,7 @@ export function GitHubImportModal({ isOpen, onClose, onImport, tasks, projectId,
selectedIssueNumber,
selectedPullNumber,
selectedGitlabKey,
+ hideImported,
},
projectId,
);
@@ -849,6 +858,7 @@ export function GitHubImportModal({ isOpen, onClose, onImport, tasks, projectId,
selectedIssueNumber,
selectedPullNumber,
selectedGitlabKey,
+ hideImported,
projectId,
]);
@@ -1147,6 +1157,13 @@ export function GitHubImportModal({ isOpen, onClose, onImport, tasks, projectId,
autoTranslateEnabled,
});
+ useEffect(() => {
+ if (!hideImported) return;
+ if (selectedIssue && isUrlImported(selectedIssue.html_url)) setSelectedIssueNumber(null);
+ if (selectedPull && isUrlImported(selectedPull.html_url)) setSelectedPullNumber(null);
+ if (selectedGitlabItem && isUrlImported(selectedGitlabItem.webUrl)) setSelectedGitlabKey(null);
+ }, [hideImported, selectedIssue, selectedPull, selectedGitlabItem, isUrlImported]);
+
if (!isOpen) return null;
// Determine state flags
@@ -1156,6 +1173,17 @@ export function GitHubImportModal({ isOpen, onClose, onImport, tasks, projectId,
// Tab-specific counts
const importedIssueCount = issues.filter((issue) => isUrlImported(issue.html_url)).length;
const importedPullCount = pulls.filter((pull) => isUrlImported(pull.html_url)).length;
+ /*
+ FNXC:GitHubImport 2026-07-15-16:30:
+ Hide imported removes imported rows from every provider's render set, while toggle-off preserves the original arrays and
+ imported counts always use the full fetched sets. Use `isUrlImported` so optimistic imports also disappear immediately.
+ */
+ const visibleIssues = hideImported ? issues.filter((issue) => !isUrlImported(issue.html_url)) : issues;
+ const visiblePulls = hideImported ? pulls.filter((pull) => !isUrlImported(pull.html_url)) : pulls;
+ const visibleGitlabItems = hideImported ? gitlabItems.filter((item) => !isUrlImported(item.webUrl)) : gitlabItems;
+ const allIssuesHidden = hideImported && issues.length > 0 && visibleIssues.length === 0;
+ const allPullsHidden = hideImported && pulls.length > 0 && visiblePulls.length === 0;
+ const allGitlabItemsHidden = hideImported && gitlabItems.length > 0 && visibleGitlabItems.length === 0;
// Empty states
const isIssuesEmpty = isIssuesEmptyState;
@@ -1357,12 +1385,20 @@ export function GitHubImportModal({ isOpen, onClose, onImport, tasks, projectId,
{t("git.gitlabNoResources", "No GitLab resources loaded")}{t("git.gitlabLoadHint", "Enter a project or group and load resources from the configured GitLab instance.")}
: null}
+ {allGitlabItemsHidden ? (
+
+
{t("git.allImportedHidden", "All loaded items are already imported")}